秋招突击——7/5——复习{}——新作{跳跃游戏II、划分字母区间、数组中的第K个大的元素(模板题,重要)、前K个高频元素}

news2025/4/16 21:18:41

文章目录

    • 引言
    • 正文
      • 贪心——45 跳跃游戏II
        • 个人实现
        • 参考实现
      • 划分字母区间
        • 个人实现
      • 参考实现
      • 数组中的第K个最大元素
        • 个人实现
        • 参考做法
      • 前K个高频元素
        • 个人实现
        • 参考实现
    • 总结

引言

  • 今天就开始的蛮早的,现在是九点多,刚好开始做算法,今天有希望能够将项目的内容整理一下,然后再修改丰富一下我的简历,这个已经拖了很久了,加把劲,累点就累点吧。

正文

贪心——45 跳跃游戏II

题目链接
在这里插入图片描述
注意

  • 所有测试用例都是可到达,所有不用考虑不能到达最终目标的情况
  • 边界存在的条件为1的情况,需要考虑一下
  • 返回的是最小跳数
  • f[i] = f[i -1] + 1,如果f[i-1]到达时已经是最小跳数,那么f[i]的最小跳数就是上一个状态的最小跳数+1
个人实现
  • 想着使用动态规划实现,因为上一个状态最小的情况下,到当前状态的最小就是默认加1,想想看怎么做的。
  • f[i]表示从0到i的最小跳数,当前是在节点i,那么就遍历在当前nums[i]范围内的所有的跳数,更新一下对应的数组就行了。
class Solution {
public:
    int jump(vector<int>& nums) {
        vector<int> f(nums.size() + 1,INT_MAX);
        f[0] = 0;
        for(int i = 0;i < nums.size();i ++){
            for(int j = 1;j <= nums[i];j ++){
                if(i + j < nums.size()) f[i + j] = min(f[i + j],f[i] + 1);
            }
        }
        return f[nums.size() - 1];
    }
};
  • 意料之外,居然没有超时,我靠,太意料之外了。这个计算量得是10的7次方最大,居然没有超时,没超时就没超时把!

在这里插入图片描述

参考实现

在这里插入图片描述
在这里插入图片描述

  • 这里是维护跳数的区间数组,在某一个区间内的最小跳数始终是固定的,而且随着往后遍历,区间的跳数是递增的,根据上述推论实现代码如下
class Solution {
public:
    int jump(vector<int>& nums) {
    vector<int> f(nums.size() + 1,0);
    for(int i = 1,j = 0;i < nums.size();i ++){
        while(j + nums[j] < i)  j ++;       // 不断将j向后移动,保证当前跳数范围包括了对应i
        f[i] = f[j] + 1;// 更新每一个节点所属的最少跳数段落信息,维护对应的数组
    }
    return f[nums.size() - 1];
    }
};

确实很巧妙,学到了,这个跳数这里应该不会再出问题了

这个可以看看之前的做的跳跃游戏原始版本,题目链接

  • 那道题也是使用类似方法,主要是通过最远距离和i之间的关系,判定能否到达最远距离,中间会不会出现断链的情况。

划分字母区间

  • 题目链接
    在这里插入图片描述
    在这里插入图片描述

注意

  • 同一个字母最多出现在一个片段中,每一个字母只能用一次
  • 片段数最多的情况
  • 所有划分结果顺序拼接,最终仍然是s
  • 小写英文字母组成
  • 长度最小是1
    保证每一个片段的字母是彼此不同的,而且要保证最终的片段数尽可能多
个人实现
  • 这里有一个约束,就是每一个字母只能在一个片段出现,不能横跨两个片段,这个怎么实现?
  • 这个题也是类似横跨区间的问题,保证一个字母出现的第一个索引和最后一个索引都是在同一个片段内部,不然就不满足约束条件,所以需要记录所有的字母的出现的两个位置。
  • 然后就是怎么合理的安排区间的问题。是否需要进行二次遍历,保证区间的相互包含,从而实现最多的划分。
  • 这里的时间复杂度目测是O(n),我需要遍历两次
class Solution {
public:
    vector<int> partitionLabels(string s) {
        vector<int> res;
        
        // 更新记录每一个元素出现的最早的位置和
        vector<pair<int,int>> word(27,{s.size() - 1,0});
        for(int i = 0;i < s.size();i ++){
            word[s[i] - 'a'].first = min(i,word[s[i] - 'a'].first);
            word[s[i] - 'a'].second = max(i, word[s[i] - 'a'].second);
        }
        cout<<word[s[0] - 'a'].first<<endl;
        cout<<word[s[0] - 'a'].second<<endl;


        // 再次遍历计算区间的长度
        int beg = word[s[0] - 'a'].first , end = word[s[0] - 'a'].second;
        for(int i = 0;i < s.size();i ++){
            end = max(word[s[i] - 'a'].second,end);
            if(i == end){
                // 遍历到尾节点,直接添加结果
                res.push_back(end - beg + 1);
                beg = i + 1;
                if(i + 1 < s.size())    end = word[s[i + 1] - 'a'].second;
            }
        }
        return res;
    }
};

在这里插入图片描述

  • 这个方法中规中矩,没有任何异常,代码量也挺多的。不过做出来了。

参考实现

序列是无序的

  • 从前往后和从后往前效果是一样的
  • 是否需要进行排序,保证他是有序的,降低问题的难度

正式思路

  • 思路和我的差不多,只不过 他是仅仅记录了每一个字母出现的最终位置,而且使用的是hashmap,这里就得讨论一下,使用数组和hashmap哪个更快。理论上来时数组更快,但是写起来比较难看。

  • 具体实现代码如下,基本上都是一致的

class Solution {
public:
    vector<int> partitionLabels(string s) {
        vector<int> res;
        
        // 更新记录每一个元素出现的最早的位置和
        vector<int> word(27,0);
        for(int i = 0;i < s.size();i ++){
            word[s[i] - 'a'] = max(i, word[s[i] - 'a']);
        }
        cout<<word[s[0] - 'a']<<endl;


        // 再次遍历计算区间的长度
        int beg = 0 , end = word[s[0] - 'a'];
        for(int i = 0;i < s.size();i ++){
            end = max(word[s[i] - 'a'],end);
            if(i == end){
                // 遍历到尾节点,直接添加结果
                res.push_back(end - beg + 1);
                beg = i + 1;
                if(i + 1 < s.size())    end = word[s[i + 1] - 'a'];
            }
        }
        return res;
    }
};

数组中的第K个最大元素

题目链接
在这里插入图片描述
注意

  • 规定了时间复杂度,O(n)只能遍历一次
  • 第K大的元素,是排序只有第K大的元素
  • 数组长度[1, 1 0 5 10^5 105]
  • 每一个元素范围是正负 1 0 4 10^{4} 104
  • 元素与元素之家存在重复的情况
个人实现
  • 这里是制定了,只能通过遍历来实现,想想看怎么做。
  • 转换一下问题思路,如果是找最大的元素,就是完整的遍历并且比较一遍,然后找最小的元素也使完整的遍历一遍,然后在比较一遍,确定一个最大值。
  • 如果是确定第二大的数字,就是如果一个数字比最大的大的话,就默认往后进行顺。
  • 所以这里想办法维护一个队列,每次都是从和队首元素进行比较,然后固定长度是K,如果超过了固定长度直接弹出最后一个元素。
  • 这样不一定是目标值。

对于队列的使用有点问题了,然后返回的是队首的元素。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        queue<int> q;
        for(auto x :nums){
            //队列是空的,直接添加
            if(q.empty())   q.push(x);
            // 如果大于队首元素,直接入队
            if(q.back() < x )   q.push(x);
            while(q.size() > k)    q.pop();
        }
       
        return q.front();

    }
};
  • 这里只能通过一半的样例,如果一开始就给我最大值,通不过测试样例,所以不行!
  • 这个方法根本就不行!
    在这里插入图片描述
  • 不会做!
  • 使用堆排序,肯定不对呀,是logN的操作复杂度
参考做法
  • 这里是一道模板题,是建立在快排的基础上实现的,所以需要背一下快排的模板,具体如下
    在这里插入图片描述
void quick_sort(int q[],int l,int r){
	if(l >= r)	return ;
	// 确定中间值、左边界、右边界
	// 中间元素不参加排序,i是从x的左侧一个开始,j是从x的右侧开始
	int i = l - 1,j = r + 1,x = q[l + r >> 1];
	while(i < j){
		do i ++; while(q[i] < x);
		do j -- ;while(q[j] > x);
		if(i < j)	swap(q[i],q[j]);
	}
	quick_sort(q,l,j),quick_sort(q,j + 1,r);
}
  • 这里的j就是最终的区分索引,所以k应该也是和j进行比较,然后再进行判定的是左边进行快排,还是右边进行快排。
  • 这是一道经典的模板题,需要好好背一下。
  • 根据模板题,好好做一下
class Solution {
public:
    int quickSort(vector<int> &nums,int l,int r,int k){
        if(l == r)  return  nums[k];
        int i = l - 1,j = r + 1 ,x = nums[(l + r) >> 1];
        while(i < j){
            do i ++ ;while(nums[i] > x);
            do j -- ; while(nums[j] < x);
            if(i < j) swap(nums[i],nums[j]);
        }   
        if(k <= j)   return quickSort(nums,l,j,k);
        else  return quickSort(nums,j + 1,r,k);
    }

    int findKthLargest(vector<int>& nums, int k) {
        return quickSort(nums,0,nums.size() - 1,k-1);
    }
};
  • 这是一个模板题,只能说是超过了我的知识范围,所以还是得不断补充完善。

前K个高频元素

题目链接

在这里插入图片描述
注意

  • 出现频率前K高的元素
  • 按照任意顺序返回
  • 数据保证答案唯一
个人实现
  • 这道题没有说数据是有序的,并不能从顺序进行考虑。
  • 最直白的做法, 统计每一个元素出现的次数,然后使用出现的次数进行排序,然后返回前k高地元素,也就是返回阈值之前的所有的元素。
class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int>  counts;
        for(auto x : nums)  counts[x] ++;
        vector<pair<int,int>>   ct;
        for(auto item : counts) ct.push_back({item.first,item.second});
        sort(ct.begin(),ct.end(),[](auto a,auto b){
            return a.second > b.second;
        });
        vector<int> res;
        for(int i = 0;i < k;i ++)   res.push_back(ct[i].first);
        return res;
       
    }
};
  • 纯硬做,直接模拟思路,完全照搬!
    在这里插入图片描述
参考实现
  • 前半部分思路是一样的,就是要统计每一个元素的出现的次数,然后形成一个key-value键值对,然后使用计数排序,实现前k个频率最高的元素的计算。
  • 具体代码如下
class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int>  counts;
        for(auto x : nums)  counts[x] ++;
        int m = nums.size();
        vector<int>   ct(m + 1,0);
        // 实现计数排序
        for(auto [k,v]:counts)  ct[v] ++;
        // 遍历前k个元素,计算一个边界次数
        int edg = m,s = 0;
        while(s < k)   s+= ct[edg --];
        // 遍历获取的满足条件的k
        vector<int> res;
        for(auto [k,v]:counts)  {
            if(v > edg)   res.push_back(k);
        }
        return res;
    }
};

遍历map的好方法

  • 使用[a,b]然后加上auto实现
for(auto [k,v] : map)

总结

  • 大概测了一下,发现自己做一道题,加上修改的总结的时间是超过了50分钟的,有点吓人,一天得花多少时间是用来做算法题。还是得快一点。
  • 可以,今天的效率蛮快的,在十一点就完成了算法题的内容,下面再补充一下关于设计模式的相关知识,然后下午就看一下我们的项目了。加油,冲 !
  • 剑走偏锋呀,感觉自己的路子不对,很多东西都没有专门走过,所以就会有很多问题,现在得转换一下思路,项目的代码我看的不是很懂,那就要从不是很懂的地方一点点开始看,一点点开始弄。现在欠缺了太多东西,后续还要增加每天一样的知识补充。其实很多东西,都是要花时间去弄的,现在就是知道MySQL的基础的东西,但是对于高可用的东西,并不了解。然后Java的多线程编程也不知道,感觉还是得花大时间。
  • 现在应该专心去弄什么?有点乱,感觉有点自暴自弃,觉得完蛋了,但是其实那几个项目并不难,跟着往后做就行了。加油吧。如果有不懂的,就去找SSM中学过的,然后就是哪里不行,补充哪里。
  • 我得调整一下自己的计划,现在欠缺的是项目还有简历,得想办法结合项目,把简历整理出来,后续再根据简历上的东西进行一点点补充。
  • 看项目有点吃力,是因为我从来没有跟着一个东西,从头到尾敲过一个项目,所以看的很吃力。
  • 晚上有点摆烂了,学了一天了,太累了,晚上注意力难以集中!!
  • 明天加油吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1899438.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【贪心 堆 优先队列】502. IPO

本文涉及知识点 贪心 堆 优先队列 LeetCode502. IPO 假设 力扣&#xff08;LeetCode&#xff09;即将开始 IPO 。为了以更高的价格将股票卖给风险投资公司&#xff0c;力扣 希望在 IPO 之前开展一些项目以增加其资本。 由于资源有限&#xff0c;它只能在 IPO 之前完成最多 k…

iOS多target时怎么对InfoPlist进行国际化

由于不同target要显示不同的App名称、不同的权限提示语&#xff0c;国际化InfoPlist文件必须创建名称为InfoPlist.strings的文件&#xff0c;那么多个target时怎么进行国际化呢&#xff1f;步骤如下&#xff1a; 一、首先我们在项目根目录创建不同的文件夹对应多个不同的targe…

LLM - 词向量 Word2vec

1. 词向量是一个词的低维表示&#xff0c;词向量可以反应语言的一些规律&#xff0c;词意相近的词向量之间近乎于平行。 2. 词向量的实现&#xff1a; &#xff08;1&#xff09;首先使用滑动窗口来构造数据&#xff0c;一个滑动窗口是指在一段文本中连续出现的几个单词&#x…

第11章 规划过程组(二)(11.8排列活动顺序)

第11章 规划过程组&#xff08;二&#xff09;11.8排列活动顺序&#xff0c;在第三版教材第390~391页&#xff1b; 文字图片音频方式 第一个知识点&#xff1a;主要工具与技术&#xff08;重要知识点&#xff09; 1、箭线图法(ADM) &#xff08;双代号网络图或活动箭线图&am…

新手如何尽快入门性能测试?

一、学习基础知识 性能测试的基本概念&#xff1a; 性能测试的定义&#xff1a;使用自动化工具&#xff0c;模拟不同的场景&#xff0c;对软件各项性能指标进行测试和评估的过程。 性能测试的目的&#xff1a;评估当前系统的能力、寻找性能瓶颈以优化性能、评估软件是否能够满…

vue.js微商城后台管理系统

一.需要运行的效果 20240701-231456 二.代码&#xff08;解析&#xff09; 首先&#xff0c;为项目添加依赖&#xff1a; yarn add element-plus --save yarn vue-router4 --save 新建一个项目包&#xff0c;然后命名为商品管理&#xff0c;在components中新建几个vue文件。 …

使用 C# 和 CefSharp 构建的全功能且快速的 Web 浏览器

SharpBrowser项目介绍 使用 C# 和 CefSharp 构建的全功能且快速的 Web 浏览器&#xff1a;SharpBrowser。 SharpBrowser是一个基于高性能的CefSharp渲染器的开源C# Web浏览器&#xff0c;采用MIT许可证。相较于Google Chrome&#xff0c;它在渲染网页时略有提升速度。该项目选…

01 Web基础与HTTP协议

1、域名和DNS 1.1 域名的概念 如果说一个主机&#xff0c;没有名字也可以完全用IP来代替&#xff0c;但是IP地址不好记忆。例如说&#xff0c;我们记一些网站的名称百度、新浪、搜狐等很好记&#xff0c;但是如果要去记百度的IP、新浪的IP、以及搜狐的IP地址&#xff0c;那将会…

基于.NET开源游戏框架MonoGame实现的开源项目合集

前言 今天分享一些基于.NET开源游戏框架MonoGame实现的开源项目合集。 MonoGame项目介绍 MonoGame是一个简单而强大的.NET框架&#xff0c;使用C#编程语言可以创建桌面PC、视频游戏机和移动设备游戏。它已成功用于创建《怒之铁拳4》、《食肉者》、《超凡蜘蛛侠》、《星露谷物…

Blazor 逐键搜索并动态反馈到url

Blazor 逐键搜索并动态反馈到url 源码 前言: 今天打开了 spotify 网页版找歌, 突然发现这个功能很抓眼球,于是试试blazor能不能模仿一下. 1. 节省时间,直接用模板开搞 新建项目,使用 Bootstrap Blazor App 模板 , 命名为 b22dynamicURL BootstrapBlazor简介: BootstrapBlaz…

uni-app 使用Pinia进行全局状态管理并持久化数据

1.引言 最近在学习移动端的开发&#xff0c;使用uni-app前端应用框架&#xff0c;通过学习B站的视频以及找了一个开发模板&#xff0c;终于是有了一些心得体会。 B站视频1&#xff1a;Day1-01-uni-app小兔鲜儿导学视频_哔哩哔哩_bilibili B站视频2&#xff1a;01-课程和uni的…

PDF压缩工具选哪个?6款免费PDF压缩工具分享

PDF文件已经成为一种常见的文档格式。然而&#xff0c;PDF文件的体积有时可能非常庞大&#xff0c;尤其是在包含大量图像或复杂格式的情况下。选择一个高效的PDF压缩工具就显得尤为重要。小编今天给大家整理了2024年6款市面上反响不错的PDF压缩文件工具。轻松帮助你找到最适合自…

C-study(五).2

逻辑运算符 连接两个完整的关系表达式。 && 逻辑与&#xff0c;ab都为真时&#xff0c;a&&b的值真&#xff0c;其余时候假。 || 逻辑或&#xff0c;ab都为假时&#xff0c;a||b的值假&#xff0c;其余时候真。 ! 逻辑非、只需要一个运算对象&#xff0c;a真&a…

数据结构——(双)链表

文章目录 1. 定义 2. 双链表和单链表的区别 3. 代码示例 3.1 双链表节点和结构定义 3.2 初始化双链表 3.3 返回双链表的长度 3.4 在指定位置插入元素 3.5 在末尾插入元素 3.6 删除指定位置的元素并返回被删除的元素 3.7 删除末尾元素 3.8 获取指定位置的元素 3.9 修…

pandas 在可空列上聚合

pandas支持group_by进行聚合&#xff0c;有如下Excel 按照A B C D四列进行聚合&#xff0c;其中D列可空也就是nan import pandas as pd from pandas import ExcelFile from pathlib import Path import os import io import sys sys.stdout io.TextIOWrapper(sys.stdout.buf…

hdu物联网硬件实验3 按键和中断

学院 班级 学号 姓名 日期 成绩 实验题目 按键和中断 实验目的 实现闪灯功能转换 硬件原理 无 关键代码及注释 /* Button Turns on and off a light emitting diode(LED) connected to digital pin 13, when pressing a pushbutton attached…

【IT领域新生必看】探索Java中的对象创建:深入理解`new`与`clone`的对比

文章目录 引言什么是new关键字&#xff1f;使用new关键字的基本语法示例&#xff1a; 什么是clone方法&#xff1f;使用clone方法的基本语法示例&#xff1a; new与clone的区别内存分配与初始化调用方式适用场景性能 new关键字的优缺点优点缺点 clone方法的优缺点优点缺点 深入…

语音模块——LSYT201B模组(超详细)

写在前面&#xff1a; 在嵌入式的学习过程中&#xff0c;语音模块是必不可少的&#xff0c;无论是做项目组合还是单个测试&#xff0c;对于语音模块我们应当有一款合适的模块。今天给大家介绍的是一款质量好、成本低、功能齐全的语音模块——LSYT201B语音模组。它的技术支持详细…

DataWhaleAI夏令营 对话要素提取 Baseline2 微调进阶

Baseline2链接&#xff1b;基于星火大模型的群聊对话分角色要素提取挑战-baseline2 - 飞桨AI Studio星河社区 (baidu.com) 数据集再构造 因为数据集中的对话数据还是标离散的&#xff0c;我们可以使用大模型自己先对数据集做一次抽取&#xff0c;构建一个新的数据集 这里对原…

12.SQL注入-盲注基于时间(base on time)

SQL注入-盲注基于时间(base on time) boolian的盲注类型还有返回信息的状态&#xff0c;但是基于时间的盲注就什么都没有返回信息。 输入payload语句进行睡5秒中&#xff0c;通过开发这工具查看时间&#xff0c;如图所示&#xff0c;会在5秒钟后在执行&#xff0c;因此存在基于…