数组 二分 35.搜索插入位置
1 二分查找 + target不在数组中, return r + 1;
34.在排序数组中查找元素的第一个和最后一个位置
1 2 3 4 5 6 [3,4,6] target = 2或7,{-1,-1} [3,4,6] target = 4 {1,1} [3,4,6] target = 5 {-1,-1} 2个二分查找 寻找左边界和右边界 寻找左边界,nums[target] == target的时候更新right 寻找右边界,nums[target] == target的时候更新left
69.x 的平方根
1 2 3 直接二分查找[0,x] target = x / mid 特判 x == 0 || x == 1 如果没找到 target, 直接返回 r (舍弃算术平方根的小数部分)
367.有效的完全平方数
1 2 二分查找 [0,num] target = num , 判断 mid * mid == num? 注意将变量设为 long long
双指针 27. 移除元素
1 使用快慢指针,快指针遍历整个数组,慢指针负责寻找不等于val值(本题该移除出来得元素值)的元素,并放进数组里(覆盖)
26.删除有序数组的重复项
1 使用快慢指针,快指针遍历整个数组,慢指针负责寻找不等于val值(本题中的前一个元素值),并放数组里(覆盖)
283.移动零
1 使用快慢指针,快指针遍历整个数组,慢指针负责寻找不等于0的值,最后再将0值覆盖给剩余的元素(注意边界)
844.比较含退格的字符串
1 '#'为删除键,如果为'#',则出栈,如果不为'#',则入栈
977. 有序数组的平方
1 使用双指针,分别在数组的两端,比较两个指针指向的元素的平方,把较大的放在数组的右边,并移动指针(向中间移动);只能移动两边中较大的元素,因为无论是正数还是负数,平方后最大的元素只能出现在两边,不能出现在中间!!
滑动窗口 209. 长度最小的子数组 滑动窗口,通过判断数组元素之间的和,对数组长度进行变化
1 2 3 4 5 while (sum >= s) { subLength = (j - i + 1 ); result = result < subLength ? result : subLength; sum -= nums[i++]; }
904. 水果成篮 思路与算法
我们可以使用滑动窗口解决本题,left 和 right 分别表示满足要求的窗口的左右边界,同时我们使用哈希表存储这个窗口内的数以及出现的次数。
我们每次将 right 移动一个位置,并将 fruits[right] 加入哈希表。如果此时哈希表不满足要求(即哈希表中出现超过两个键值对),那么我们需要不断移动 left,并将 fruits[left] 从哈希表中移除,直到哈希表满足要求为止。
需要注意的是,将 fruits[left]从哈希表中移除后,如果 fruits[left]在哈希表中的出现次数减少为 0,需要将对应的键值对从哈希表中移除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public : int totalFruit (vector<int >& fruits) { int n = fruits.size (); unordered_map<int , int > cnt; int left = 0 , ans = 0 ; for (int right = 0 ; right < n; ++right) { ++cnt[fruits[right]]; while (cnt.size () > 2 ) { auto it = cnt.find (fruits[left]); --it->second; if (it->second == 0 ) { cnt.erase (it); } ++left; } ans = max (ans, right - left + 1 ); } return ans; } };
76. 最小覆盖子串 滑动窗口—困难
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 class Solution { public String minWindow (String s, String t) { int slen = s.length(); int tlen = t.length(); if (slen == 0 || tlen == 0 || slen < tlen){ return "" ; } char [] charArrayS = s.toCharArray(); char [] charArrayT = t.toCharArray(); int [] winFreq = new int [128 ]; int [] tFreq = new int [128 ]; for (char c : charArrayT){ tFreq[c]++; } int distance = 0 ; int minLen = slen + 1 ; int begin = 0 ; int left = 0 ,right = 0 ; while (right < slen){ if (tFreq[charArrayS[right]] == 0 ){ right++; continue ; } if (winFreq[charArrayS[right]] < tFreq[charArrayS[right]]){ distance++; } winFreq[charArrayS[right]]++; right++; while (distance == tlen){ if (right - left < minLen){ minLen = right - left; begin = left; } if (tFreq[charArrayS[left]] == 0 ){ left++; continue ; } if (winFreq[charArrayS[left]] == tFreq[charArrayS[left]]){ distance--; } winFreq[charArrayS[left]]--; left++; } } if (minLen == slen + 1 ){ return "" ; } return s.substring(begin,begin+minLen); } }
59. 螺旋矩阵 II 模拟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class Solution {public : vector<vector<int >> generateMatrix (int n) { vector<vector<int >> res (n, vector <int >(n, 0 )); int startx = 0 , starty = 0 ; int loop = n / 2 ; int mid = n / 2 ; int count = 1 ; int offset = 1 ; int i,j; while (loop --) { i = startx; j = starty; for (j = starty; j < n - offset; j++) { res[startx][j] = count++; } for (i = startx; i < n - offset; i++) { res[i][j] = count++; } for (; j > starty; j--) { res[i][j] = count++; } for (; i > startx; i--) { res[i][j] = count++; } startx++; starty++; offset += 1 ; } if (n % 2 ) { res[mid][mid] = count; } return res; } };