- 博客(109)
- 收藏
- 关注
原创 C++、操作系统、计算机网络等需要巩固的知识点(自用,更新中)
面试C++、操作系统、计算机网络、网络编程、设计模式等需要巩固的知识点的整理。(自用的)
2022-07-28 19:41:29
714
1
原创 646.最长数对链(动态规划)
解题思路:动态规划(最长升序子序列变体)dp[i]表示到索引为i的这个元素为止,有多少个满足要求的数对,即第一个元素大于前一个元素的第二个元素。动态转移方程if(pairs[i][0]>pairs[j][1]){ dp[i]=max(dp[i],dp[j]+1);但是由于给的数组是无序的,因此需要首先对数组作处理。首先数组按照第二个元素的升序排列,而不是按第一个元素的升序排列,原因是前者能够为后面留下更多的空间。sort(pairs.begi..
2021-11-25 19:26:20
146
原创 131.分割回文串
解题思路:使用深度优先搜索,一旦搜索到回文字符串,那么就进入递归,并且递归中从上一次搜索的下一个位置开始搜索。具体见代码。class Solution { vector<vector<string>> ret;public: //判断是否是回文字符串 bool calc(const string& s){ int i=0,j=s.size()-1; while(i<j){ if(s..
2021-11-23 19:33:52
98
原创 384.打乱数组
解题思路:用一个辅助数组vec,大小与传入数组一样,并且元素是生成的随机数。使得vec按照升序排序,并且原始数组也按照其排序方法排序。通过这种方式来随机打乱数组。举个例子:nums [2,3,1] vec [10,6,30]那么vec按升序排序就是vec[0]和vec[1]交换,那么nums[0]和nums[1]也交换。所以nums [3,2,1] vec [6,10,30]具体代码如下class Solution { vector<int> m_nums;..
2021-11-22 19:40:00
1025
原创 934.最短的桥(广度优先搜索)
解题思路方法1:暴力法使用深度优先搜索,讲两个岛屿的坐标存储到两个数组中,然后用两个for遍历数组,找到最小置。很暴力,时间和空间复杂度也很高。class Solution {public: int shortestBridge(vector<vector<int>>& grid) { int m=grid.size(),n=grid[0].size(); vector<vector<bool>>vi.
2021-11-01 21:05:02
201
原创 51.N皇后(回溯法)
解题思路:回溯法主函数初始化一个全为’.'的二维数组,哪个位置可以放置皇后棋子,修改为’Q’即可。axis数组用来存放已经放置棋子的坐标。 //主函数 vector<vector<string>> solveNQueens(int n) { vector<vector<string>>ans; vector<string>board(n,string(n,'.')); ve..
2021-11-01 19:35:09
133
原创 417.太平洋大西洋水流问题
解题思路:一开始自己的思路是看每一个点是否能流到太平洋和大西洋,很复杂,各种细节考虑不到。看了题解觉得这个方法很好,记录一下。我们从四个边开始往高处走,能走到的位置就是能流到对应边旁边的洋流。can_reach_p,(太平洋 pacific)代表能到达太平洋;can_reach_a,(大西洋 atlantic)代表能到达大西洋。假如某个点的can_reach_p和can_reach_a都为true,说明符合条件。具体思路看代码。class Solution {public: vec.
2021-10-31 20:12:01
121
原创 240.搜索二维矩阵II
解题思路看到两个关键词,有序+寻找目标值,很自然的想到二分查找。当二维数组中的某一行首元素<=target,并且尾元素>=target 时,那么target可能在这一行。因此,首先寻找所有可能有target的行,保存在数组中。接下来对这些行,进行二分查找,找到就返回true,没找到就对下一个符合条件的行进行二分查找。假如最后都没有找到target,那就是matrix二维数组中不存在target,返回false。class Solution {public: bool b_.
2021-10-25 22:24:55
144
原创 81.搜索旋转排序数组II(数组旋转后二分查找)
记录一下:if(nums[left]==nums[mid]){ //无法判断哪个区间是升序的 ++left; }假如是上面这种情况,反正是寻找有无target,两个元素相等,直接让left往右移动一个,直到能够判断左边还是右边是升序!class Solution {public: bool search(vector<int>& nums, int target) { .
2021-10-21 22:11:12
86
原创 524.通过删除字母匹配到字典里最长单词
思路:因为要找长度最长且字母序最小的字符串。因此先对dictionary进行排序,按字符串长度降序,假如长度相同就按字母序,即默认的string排序即可。接下来遍历dictionary每一个string元素,记为dic,看是否满足要求。辅助函数,判断dic是否是s的子串:假如dic长度大于s,那么必然不可能由s删除字符得到dic,返回false;否则就用双指针的方法,判断即可,具体流程见代码。class Solution {public: bool help(const stri..
2021-10-21 20:38:34
137
原创 665.非递减数列
思路:初始化一个bool类型的变量flag,true表示改动的次数未用,false表示改动的次数用掉了。先看一下前两个元素是否满足非递减要求,不满足flag初始化为false。从nums[1]开始,每次和后面一个元素比较,假如不满足非递减,就选择下面两种情况中的一个改变元素:1 [3,5,4,6] 5>4且4>3,那么要把5变成4;即i=1,nums[i+1]>=nums[i-1]; nums[i]=nums[i+1];2 [5,6,3,7] 6>3且3<5,那..
2021-10-20 21:13:42
89
原创 406.根据身高重建队列
思路:按身高降序排列,假如身高一样就按升序排列。接下来,创建一个数组ret保存结果,遍历people数组;people第二个元素的值就是该people要插入数组ret中的位置,因为身高是按降序排列,而身高相同则按k升序排列,因此一定不会影响到后面的元素,如下图所示。class Solution {public: vector<vector<int>> reconstructQueue(vector<vector<int>>& peo.
2021-10-20 20:24:36
162
原创 453.最小操作数使数组元素相等
关键:让n-1个元素加1,就相当于选一个元素-1;选n-1个元素加1,加到所有元素相等,就相当于选1个元素减1,减到所有的元素都等于最小元素。class Solution {public: int minMoves(vector<int>& nums) { //得到nums中的最小元素 int min_val=INT_MAX; for(auto num:nums) { min_va..
2021-10-20 19:56:28
152
原创 union中有struct的情况-从内存分析
union中的每个成员共用一块内存,且首地址相同;这块内存必须大于等于union中最大成员的字节数。举个例子:union U中有两个成员,一个是int型的a,4个字节;一个是结构体STU,考虑对齐,16个字节。struct STU { int b; long long c;};union U{ int a; STU stu;};首先使用结构体初始化union U,查看其内存分布情况:U u; STU m_stu; m_stu.b = 6; m_stu.c = 66;
2021-09-28 15:24:13
1036
原创 算法学习:1-1 贪心算法
所谓贪心算法,就是每次操作保证都是局部最优解,以至于最终的结果是全局最优解。习题1:455.分发饼干使用贪心算法,关键在于找到贪心策略,即每一步操作都是局部最优解。由题可知,要尽可能满足多的孩子,只要给胃口值最小的孩子分配能让他满足的最小尺寸的饼干,这就是本题的贪心策略。class Solution {public: int findContentChildren(vector<int>& g, vector<int>& s) {
2021-09-27 22:26:43
3911
5
原创 871.最低加油次数(动态规划)
解题思路:动态规划dp[i]表示,加油i次最远可以到达的距离;关键,如果经过j次加油可以到达i这个位置的加油站,那么就可以在这个站加油获得油量,从而更新dp[j+1]class Solution {public: //stations[0]是加油站位置,stations是加油站有多少汽油 int minRefuelStops(int target, int startFuel, vector&.
2021-09-27 19:09:12
391
原创 650.只有两个键的键盘(动态规划)
解题思路:动态规划对于一个数n,他需要进行多少次的复制全部和粘贴的操作,比如25个A,最大能被25整除(比25小的数中)2的数是5,那么我需要复制5个A粘贴5次就可以得到25个A,那么怎么得到5个A,最大能被5整除(比5小的数中)的数是1,因此只能通过复制一个A并粘贴5次。假设 n%m=0,n/m=min_val; m的范围[1,n-1];那么动态转移方程为:dp[n]=dp[m]+(min_val-1)+1;dp[m]代表要得到m个A最少需要多少次操作;min_val-1代表需要对m个A进行.
2021-09-19 21:16:51
146
原创 208.实现Trie树(字典树与哈希表实现)
1 字典树Trie树又称字典树,字典树的数据结构如下所示;下面这颗字典树包含的字符串集合是{ab,aza};每一个类Trie中包含一个vector<Trie*>children(26),和isEnd(标记一个字符串的尾);比如我们要插入abc,先看根节点node中的的children[a-‘a’]是否有指向下一个Trie的指针,有的话代表存在第一个字符为‘a’的前缀,那么往下走,node=node->children[a-'a‘];再看这个节点的children[b-‘a’]中.
2021-09-19 20:44:12
584
原创 cin读入多行用空格隔开的数字并放进不同vector-利用cin.get()
合并有序链表输入:1 6 12 183 5 9 20输出:1 3 5 6 9 12 18 20下面所说的忽略也可以理解成丢弃!首先我们要用cin把用户的输入存入两个数组中。很简单的一个想法,让cin去缓冲区读数据赋值给num,直到遇到缓冲区中的’\n’(Enter),就跳出本次cin。我们知道,cin作为一个输入流对象会忽略缓冲区中的空格,Enter和结束符,所以我们要怎么去拿到这个Enter呢(判断换行)?当我们输入1 6 12 18,按下Enter键,那么字符串“1 6 12 1
2021-09-08 21:19:14
3274
原创 剑指offer-64.滑动窗口的最大值
解题思路:分类讨论用max_val维护前一个滑动窗口的最大值;res存放每个窗口的最大值;首先要计算第一个窗口的最大值,记录max_val;往后滑动一个,删除了一个最左边元素,以及增加了一个最右侧元素。情况1 最右侧元素,大于等于上一个窗口的max_val,那么毫无疑问,这个窗口的最大值就是最右侧元素,更新max_val;情况2 最右侧元素,小于上一个窗口的max_val;那么就看删除的那个元素,假如删除的那个左侧元素等于max_val,那么就要重新计算最大值max_val,注意,此时要更.
2021-09-01 16:47:13
119
原创 剑指offer-63.数据流中的中位数
解题思路:用大顶堆和小顶堆解决这个问题。大顶堆就是首元素是最大值;小顶堆则是最小值。现在设计一个大顶堆get_max,用于保存比中位数小的数,首元素是最大值;小顶堆get_min,用于保存大于或等于中位数的数,首元素是最小值。举个例子数据流1,2,3,4,5,6get_max [1,2,3]get_min [4,5,6]分类讨论我们规定get_min要么比get_max的容量大1个,要么等于。所以,数据流个数是偶数个,我们只要取出get_min的最小值和get_max的最大值,然.
2021-09-01 16:22:20
130
原创 剑指offer-56.删除链表中重复的结点
解题思路:链表中重复元素的删除,因为重复的结点都要删除,所以需要一个前驱结点pre。因为删除一个结点的基本操作是node->next=node->next->next;(删除node的下一个结点);我们设置当前结点cur,假如判断当前结点cur与后面几个结点是重复的结点,需要删除,那么可以逐个删除与cur重复的结点,但是我们还需要把cur这个结点也删除,要删除cur这个结点时,没有前驱结点就不好删除了,所以需要pre这个前驱结点。/*struct ListNode { .
2021-08-31 16:10:05
106
原创 剑指offer-49.把字符串转换成整数
解题思路:两个辅助函数1 判断[left,right]范围内字符串是否有效,即是否存在数字以外的字符,存在就返回false。2 假如上面的函数判断字符串有效,将[left,right]范围内的字符串转换成整数。接下来只要确定边界left和right就可以了,right就是str的长度-1,即最后一个元素的下标;因为str[0]是’+‘或’-‘也是合法的,所以假如str[0]是’+‘或’-’,left就是1,否则left就是0。并且根据str[0]的符号可以确定整数的正负,用flag来记录正负1/-.
2021-08-31 14:26:02
129
原创 剑指offer-48.不用加减乘除做加法(位运算)
解题思路:用位运算做加法。s=a+b,s就是不考虑进位的结果+进位,直到进位等于0。具体见代码:class Solution {public: //用位运算 int Add(int num1, int num2) { while(num2!=0){ //保存进位 int c=((unsigned int)(num1&num2))<<1; //第一次进来,先不考虑进位,看各位.
2021-08-31 13:59:33
101
原创 剑指offer-47.求1+2+...+n(递归)
解题思路递归,但是常规来说,递归要用到终止条件,这里的终止条件是if(n==1)return 1;但是题目要求不能使用if语句,所以为了解决这个问题,就需要用到&&的性质。&&1 &&两侧的对象的结果都要转换为bool类型2 &&左侧的对象为假,那就不看右侧的对象了,直接返回false。因此,代码如下:class Solution {public: int Sum_Solution(int n) { /.
2021-08-31 13:30:12
361
原创 剑指offer-46.孩子们的游戏(圆圈中最后剩下的数)
解题思路:创建一个数组模拟这个过程。1 创建一个大小为n的数组,[0,n-1]2 开始模拟报数,报到m-1的那个位置,删除之。这里我用到的是迭代器,所以有一种特殊情况,假如最后一个孩子报到m-1,那么删除之,并且下一次报数要从第一个孩子开始。而erase(iterator position)返回的是end(),因此要把迭代器更新到begin()。class Solution {public: int LastRemaining_Solution(int n, int m) { .
2021-08-31 13:18:38
124
原创 剑指offer-45.扑克牌顺子
解题思路:1 先按升序排序数组,用count记录0的个数2 从非0数字开始,用need0记录需要的0,假如后一个数字的比前一个数字大1,那么不需要癞子0,因为它们本来就连续;假如大2,那就需要1一个0,count-=1…以此类推。假如最后count<0,说明count不够用,即无法形成顺子。3 注意,假如有相同数字,返回false。class Solution {public: bool IsContinuous( vector<int> numbers ) { .
2021-08-31 12:46:04
98
原创 剑指offer-44.翻转单词序列
解题思路维护一个栈,存放单词和空格。创建一个空串string word;假如没有遇到空白‘ ’,word+=str[i];假如遇到空白,说明一个单词到此结束,把word压栈,再把空格‘ ’压栈,字符串word清空,word=“”;最后让字符串res逐个加上栈顶元素即可。class Solution {public: string ReverseSentence(string str) { int n=str.size(); if(n==0)return s.
2021-08-31 12:23:23
97
原创 剑指offer-37.数字在升序数组中出现的次数
解题:1 暴力2 双指针3 但是我们看到升序数组,应该想到二分法二分查找:target=k1 查找第一个出现的k的位置2 查找第一个大于k的值的位置熟练上面两种搜索的做法,要注意边界条件。class Solution {public: int GetNumberOfK(vector<int> data ,int k) { int n=data.size(); if(n==0) return 0; //.
2021-08-29 22:24:50
114
原创 剑指offer-23.丑数
解题思路:丑数就是2x3y5z,所以,根据这个定义,也就是说,我们对每个丑数*2、*3、*5,它依然是个丑数。创建一个数组,大小为index,填充这个数组,最后arr[index-1]就是第index个丑数。根据题意,index[0]=1,定义三个变量i2=0,i3=0,i5=0,分别对应将要乘以2、3、5的丑数的下标。每次比较三个丑数,最小的那个丑数放入数组,比如arr[i2]*2最小,放入arr[i]这个位置,那么下一次要乘以2的丑数的下标就要往后移动一个位置,即++i2;i3、i5同理。c.
2021-08-29 21:01:31
107
原创 剑指offer-27.字符串的排列
解题思路:可以看到是一个全排列的问题,所以很显然用到回溯法,问题是重复的元素要去除。因此,我们需要先将字符串排序,将重复的字符放到一起;再加一个规则,就是重复的字符,下标i的字符使用了以后才可以使用下标i+1的字符。class Solution {public: vector<string>vec; vector<string> Permutation(string str) { sort(str.begin(),str.end()); .
2021-08-25 21:22:24
111
原创 剑指offer-26.二叉搜索树与双向链表
解题思路递归解法,中序遍历+前驱节点注意前驱节点是引用!/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { }};*/class Solution {public: TreeNode* Convert(TreeNode* pRootOfTree) { .
2021-08-25 21:01:11
110
原创 剑指offer-23二叉搜索树的后序遍历序列
解题思路:1 递归,借助中序遍历class Solution {public: unordered_map<int,int>m; bool VerifySquenceOfBST(vector<int> sequence) { int n=sequence.size(); if(n==0)return false; //获得中序序列 vector<int> inordered(seque.
2021-08-24 21:56:37
93
原创 剑指offer-17.树的子结构(递归)
解题思路:递归看到树就想到递归辅助函数设计一个辅助函数,判断根节点相等的两颗树a,b,判断b是否是a的子树,保证传进辅助函数的不是空树。终止条件:(注意a、b都不空)假如b空,那么a无论空不空,说明a包含b,返回 true;假如a空,b不空,说明a不包含b,返回false;假如a、b都不空:a 值相等,递归判断左右子树,都为真才能说明a包含bb 值不相等,返回false;必须要都满足要求才算包含,所以用&&。主函数逻辑两棵树p、q,假如有一颗为空,根据空树不是任.
2021-08-23 17:02:03
102
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人