双指针
双指针
baixiaofei567
如果十年前没种树,那最好的时间是现在
展开
-
80. 删除有序数组中的重复项 II
两种方法法一:遍历然后erase,维护一个pre作为前一个数字,和前一个数字的出现次数,如果当前和pre相等,就让cishu++,不相等就更新pre和cishu。如果cishu大于2就erase当前迭代器,记得将it–,这个很重要,而且要让cishu也–。法二:快慢指针,这个快慢指针确实niubility,我是不太想得出,慢指针是放置完的所有数据的后一位,就是待放置的位置,快指针一直猛冲,就快指针和慢指针-2比,如果相等,就让快指针++,因为慢指针-2和慢指针-1,起码有两个数字是一样的了,那么快指针.原创 2021-04-07 01:17:55 · 188 阅读 · 0 评论 -
697. 数组的度
和数量有关的子序列,当然是滑动窗口,而且是比较简单的滑动窗口。滑动窗口,如果某个窗口新加了r之后,如果达到了maxn,就缩减左边,缩减到window[r]不为maxn为止,每次在中间就要进行判断r-l+1和maxn谁更小,这个很重要,不是在外面判断的class Solution {public: int findShortestSubArray(vector<int>& nums) { //滑动窗口,如果某个窗口新加了r之后,如果达到了maxn,就缩减左边.原创 2021-03-30 01:37:19 · 90 阅读 · 0 评论 -
524. 通过删除字母匹配到字典里最长单词
双指针,一个指针在s上走,一个指针在字典里的每个字符串上走。走完判断r是否和字典里的这个字符串的长度相等,如果相等就可以试试看用这个字符串来更新res。字典序比较小的意思是aa<ab,所以要用d[i]和res比一下谁更小,d[i]更小就行了先比长度,如果长度一样再比字典如果不想写这么多if-else也可以先对字典进行排序,这样子字典序小的就在前面,我们只要判断长度是否大于res就可以更新了class Solution {public: string findLongestWord(.原创 2021-02-18 01:10:47 · 116 阅读 · 0 评论 -
680. 验证回文字符串 Ⅱ
这题其实也不错!回文=双指针如果左右相等,就收缩范围。如果不相等,我们就要考虑删除一边了,比如abbab,看似删除a和删除b都可以,但是删除b才是正确答案。所以我们两边都删除试试,删除一次之后就没机会了,所以我们写一个函数判断普通的回文串,一个判断l+1,r。一个判断l,r-1。只要有一个是正确的就可以了,如果两个都不正确就返回falseclass Solution {public: bool isValid(string s, int l, int r){ //判断当前字符.原创 2021-02-18 01:07:43 · 111 阅读 · 0 评论 -
345. 反转字符串中的元音字母
用一个string来存元音字母集合,用string的find函数查找s[i]出现的位置,如果成功找到是返回下标,如果找不到返回的是-1。用while分别找到l和r的元音字母,记得控制越界!!如果l<r就交换,不然就怕l>r了就反着交换了,结束的条件是l>=r。记得交换完之后l++,r++,不然l和r永远停在元音上了就死循环了class Solution {public: string reverseVowels(string s) { //元音字母aeiou.原创 2021-02-18 01:03:23 · 96 阅读 · 0 评论 -
633. 平方数之和
也是双指针,为了做剪枝操作,r就从sqrt©开始,防止sum越界,就用long long来表示sum。此处双指针l和r可以相等!!case:2=11+11class Solution {public: bool judgeSquareSum(int c) { //还是双指针,从0和sqrt(c)开始 long long l = 0, r = (int)sqrt(c); long long sum; //可能会有超大整数,我们的su.原创 2021-02-18 01:00:13 · 110 阅读 · 0 评论 -
167. 两数之和 II - 输入有序数组
妥妥的双指针,两边夹class Solution {public: vector<int> twoSum(vector<int>& numbers, int target) { //双指针,两边夹 int l = 0, r = numbers.size()-1; while(l<r){ if(numbers[l] + numbers[r] == target){ .原创 2021-02-18 00:58:22 · 94 阅读 · 0 评论 -
287. 寻找重复数
法一:抽屉法,放回原位,在放的过程中,如果自己不在原位,但是原位已经被自己的复制品霸占了,就直接返回当前数字,当前数字就是重复的,否则就交换,把当前数字放回原位。缺点就是要swap,会改变原数组.法二:快慢指针,只要是有重复数字就一定存在环。这个环和链表的环差不多,比如31342这个数组,我们从0开始走,走到当前数组的某一位,就把那一位的值作为下一步要走的下标。0->3->4->2->3->4->2,这就进入了环。但是这里的快慢指针怎么走呢,如何体现快慢的思想,我们把.原创 2021-02-15 01:01:53 · 118 阅读 · 0 评论 -
28. 实现 strStr()
妥妥的滑动窗口,收缩到cnt不满足need.size()class Solution {public: int strStr(string haystack, string needle) { //首先要判断是否有这个才行,滑动窗口判断即可 //在窗口里的东西都满足后判断needle和窗口是否相等,如果相等就返回left if(haystack.length() < needle.length()) return -1; i.原创 2021-02-02 01:33:01 · 87 阅读 · 0 评论 -
647. 回文子串
又是回文子串,中心扩散法必须记住!!中心扩散法的特点是可能有1个中心or两个中心。在遍历的时候两个中心的情况也要考虑!!这就是中心扩散法的模板class Solution {public: int countSubstrings(string s) { //计算有几个回文子串,dfs? //之前有最长回文子串,是用中心扩散的,为什么回文子串是中心扩散??两个也可以形成回文子串啊 //中心可能一个点or两个点 int res = 0.原创 2021-01-31 01:42:37 · 57 阅读 · 0 评论 -
567. 字符串的排列
长度不满足时收缩。class Solution {public: bool checkInclusion(string s1, string s2) { //要在字符串中搜索子集问题,或者排列之类的问题,如果可以通过双层循环解决,一定可以通过滑动窗口解决 //这tm比最短更简单!!只要valid等于need.size直接返回就行了 if(s1.length() > s2.length()) return false; un.原创 2021-01-30 01:22:21 · 89 阅读 · 1 评论 -
438. 找到字符串中所有字母异位词
滑动窗口典型题,重要的就是搞清楚left收缩那个地方,什么时候要收缩,什么时候缩完了。有些时候是长度不满足要求了,有些时候是window里面的字符不满足要求了,就收缩结束了。class Solution {public: vector<int> findAnagrams(string s, string p) { //hash+滑动窗口 vector<int> res; if(s.length() < p.leng..原创 2021-01-30 01:19:37 · 74 阅读 · 0 评论 -
141. 环形链表
要记住这样的写法,如果head为空或者单结点,直接false。如果不是就把慢指针设为head,快指针设为head->next,防止一开始直接相等。while结束的条件就是他俩相等,内部先判断快指针是否为null或者快指针的下一个是否为null,这很重要,很容易出错,这里只要判断快的,因为五环的话快的一定先走完。最后返回true/** * Definition for singly-linked list. * struct ListNode { * int val; * L.原创 2021-01-28 01:01:11 · 62 阅读 · 0 评论 -
76. 最小覆盖子串
hard做的人想吐,暴力超时,要用滑动窗口和map,最重要的操作是弹出左边那些不要的元素,这样更新的left再去和minLen比。然后left再++,因为left++了,所以肯定不满足了,让right也++,直到right走到最后一位class Solution {public: string minWindow(string s, string t) { if(t.length() == 0) return s.substr(0,1); if(t.length.原创 2021-01-26 01:53:34 · 70 阅读 · 0 评论 -
19. 删除链表的倒数第N个节点
链表=双指针=空间鲁棒性快指针先走n步,当快指针走到null时,慢指针指向倒数第n个。因为遍历一遍,所以用一个int变量记录快指针走了几步,当快指针走的步数大于等于n时,才让慢指针开始走。因为要删除,所以要来一个pre指针记录当前指针的前驱指针,删除操作就是直接让pre指向当前指针的next即可。最后判断,如果快指针在走n步直接走到结尾了,那么证明要删除头结点,直接返回head->next即可,通过判断pre是否为空来看是否是删除头。否则就删除slow指针指向的结点,最后返回head/** *.原创 2021-01-18 01:33:58 · 78 阅读 · 0 评论 -
15. 三数之和
很好的一道题,难点有2,控制时间复杂度和去重操作。去重操作可以通过先将数组排序解决,如1,0,-1,1,那么1,0,-1和0,-1,1就是重复了,这个用set去重也不简单,因为这两个数组虽然数字一样但是完全不同。所以我们将其排序为-1,0,1,1,这样1只能在第三个数字取到了,我们只要保证第三个数字不要取重复的就行了,也就是和前一次取到的第三个数字比较,如果相等直接continue。控制时复可不简单,用双指针的操作,这里看似两个循环,但是最多也就循环n次,因为如果指针3和指针2相等了就不用再走了,因为.原创 2021-01-17 01:50:42 · 100 阅读 · 0 评论 -
283. 移动零
两种方法:1.双指针:先将left和right都指向0,当right大于等于数组个数时结束循环。循环里的过程时当left指向0就停住,当right指到非零数就交换。2.消0再补0:遍历数组,如果等于0,就erase;然后将0的个数++,方便等下在后面补0,并将it–,因为erase一个数字之后,后面的数会自动补上来,it指向的就是下一轮本应遍历的数,然后it再++就会跳过后面那个数,所以要让it–。最后在后面puhs_back进0class Solution {public: /*stat.原创 2021-01-13 00:48:20 · 70 阅读 · 1 评论 -
剑指offer——和为S的两个数字C++
很简单的双指针,两边夹准则就行,而且是递增序列,必须双指针了。class Solution {public: vector<int> FindNumbersWithSum(vector<int> array,int sum) { //找两个数的啥啥,就考虑双指针 vector<int> res; if(array.size() < 2) return res; int low = 0, h.原创 2021-01-03 01:27:07 · 138 阅读 · 0 评论 -
剑指offer——和为S的连续正数序列C++
两个方法,不知道为什么暴力比滑动窗口更耗时??1.暴力,因为最多只能到sum/2+1,比如9,就有4和5,所以要一直推到5为止。2.滑动窗口,定义两个指针,从1和2开始往后走,如果当前窗口内的值等于sum就加入数组,如果大于就将前一个指针++,缩小窗口。如果小于就将后一个指针++,扩大窗口。当两者相等时退出循环(用Low!=sum/2+1也行)。为什么是相等退出循环呢,因为窗口值太大才会让low++,如果一直加到等于high,证明已经没办法缩小窗口了。区间求和,就要想到滑动窗口class Solu.原创 2021-01-03 01:25:11 · 135 阅读 · 0 评论 -
剑指offer——两个链表的第一个公共结点C++
链表题一定要想到快慢指针三种方法:1.用一个map记录第一条链表每个结点是否出现,遍历第二条时判断即可。2.我称之为相亲相爱法,因为两条链表的长度不确定,所以让两个指针分别走1+2两条链表的长度就可以了,这样走的就是相等了。两个结点相等时退出循环(这样就算两个结点都指向空结点也不会死循环)。当1为空,就让1指向链表2的头,2为空,就让2指向链表1的头。3.算出两条链表的长度len1和len2,假设len1>len2,就让链表1的指针先走len1-len2步,然后再一起走就行了/*stru.原创 2020-12-30 01:59:26 · 160 阅读 · 0 评论 -
1085 Perfect Sequence (25分)三种方法
#include<iostream>#include<algorithm>using namespace std;typedef long long ll;int main(){ int n, p; cin>>n>>p; ll a[100010]; for(int i = 0; i<n; i++){ cin>>a[i]; } sort(a,a+n); int ma原创 2020-11-01 02:55:24 · 173 阅读 · 0 评论 -
1048 Find Coins (25分)
Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for eac原创 2020-10-23 01:15:22 · 168 阅读 · 1 评论 -
80. 删除排序数组中的重复项 II
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。示例 1:给定 nums = [1,1,1,2,2,3],函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。你不需要考虑数组中超出新长度后面的元素。示例 2:给定 nums = [0,0,1,1,1,1,2,3,3],函数应返回新长度 length =原创 2020-08-13 00:07:54 · 68 阅读 · 0 评论 -
26. 删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。示例 1:给定数组 nums = [1,1,2],函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。你不需要考虑数组中超出新长度后面的元素。示例 2:给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回新的长度 5, 并且原数组 nums 的原创 2020-08-13 00:00:06 · 70 阅读 · 0 评论 -
11. 盛最多水的容器
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。说明:你不能倾斜容器,且 n 的值至少为 2。图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。示例:输入:[1,8,6,2,5,4,8,3,7]输出:49class Solu原创 2020-08-10 22:45:01 · 118 阅读 · 0 评论