- 一种特殊的算法, int start = 0, end = n - 1; int i = 0; while (i <= end) { if (nums[i] < pivot) { swap(nums, i, start); start++; i++; } else if (nums[i] == pivot) { i++; } else { swap(nums, i, end); end--; } }注意start++后i++, end--后i不用++, 因为start不可能指向2
- Binary SearchRemember the graph!First compare the mid with the end to decide which side the mid is inThen for each side, compare the target with (start, mid) or (end, mid), to decide which side of mid the target is in
- Similar to 3sum, but no need to check duplicates
- Backtrackingsort firstadd every tmp result
- use rowZero, colZero来记录第一行第一列是否含有0然后遍历其他的行和列,若为0,则matix[i][0], matrix[0][j]都设为0然后再遍历第一行第一列,把为0 的全部设为0最后根据rowZero和colZero来设第一行和第一列
- sort interval by startloop continue update current interval's end my max(cur.end, next.end) if overlap while(i<intervals.size()){ Interval inter = intervals.get(i); while(i< intervals.size() && inter.end >= intervals.get(i).start){ inter.end = Math.max(inter.end, intervals.get(i).end); i++; } res.add(inter); }
- 最优算法:贪心法,时间复杂度 O(n) 用一个变量保存你最多可以跳多远• 次优算法:动态规划,时间复杂度 O(n^2) • state: f[i]代表我能否跳到第i个位置• function: f[i] = OR{f[j]} 其中 j < i && j能够跳到i • 解释:什么是 OR 运算?• 比如满足 j < i && j 能够跳到 i 的 j 有 0, 1, 4, 7 • 那么 f[i] = f[0] || f[1] || f[4] || f[7]• initialize: f[0] = true; • answer: f[n-1] int reach = 0; for(int i=0; i<nums.length; i++){ if(reach < i) return false; reach = Math.max(reach, nums[i]+i); } return true;
- 一次遍历即可,可以用类似two pointers的格式来写注意只有1个值的时候不需要箭头
- Binary Searchthe condition is A[mid + 1], A[mid] and A[mid - 1]
- Two pointers int i = 0, j = 0; for (i = 0; i < n; i++) { while (j < n - 1 && nums[j] == nums[j + 1]) { j++; } nums[i] = nums[j]; j++; if (j == n) { break; } } return i + 1;
- • state: sum[i][j]从0,0 到 i, j 的最小sm• function: f[i][j] = min(f[i-1][j], f[i - 1][j-1]) + A[j][j]• intialize: f[i][0] = sum(0 - i, A[i][0])f[i][i] = sum(0 - j, A[i][i])• answer: min(sum[m - 1][j])
- Backtracking starts from each cell,modify the visited cell to a special character to avoid duplicates
- 对撞型指针while (start < end) {max = Math.max(max, (end - start) * Math.min(heights[start], heights[end]));if (heights[start] < heights[end]) {int height = heights[start];while (start < end && heights[start] <= height) {start++;}} else {int height = heights[end];while (start < end && heights[end] <= height) {end--;}}}
- Use the findkth functionGet the start + k/2 value for both array, if val1 < val2 then search start1 + k/2, start2 for k/2, or vice versaO(log (m + n))
- Greedy int profit = 0; for(int i = 1; i < prices.length; i++){ if(prices[i] > prices[i-1]) { profit += prices[i]-prices[i-1]; } }
- 用stack,把比当前小的都pop出来,说明当前到了某个parent的右边keep 一个lowBound是当前最后一个弹出的值,若当前值小于lowBound则无效优化为空间O(1)的方法是把原先数组用作stack也可以用divide&conquer,查看后面是不是先都比root小,再都比root大,然后迭代
- 两根指针, int i = 0, j = 0; int n = nums.length; for (i = 0; i < n; i++) { while (j < n && nums[j] == 0) { j++; } if (j < n) { nums[i] = nums[j]; j++; } else { nums[i] = 0; } }
- 对撞型指针 while (i < j) { if (height[i] < height[j]) { int h = height[i]; while (i < j && height[i] <= h) { res += h - height[i]; i++; } } else { int h = height[j]; while (i < j && height[j] <= h) { res += h - height[j]; j--; } } }
- public int getSum(int a, int b) { if (a == 0) return b; if (b == 0) return a; while (b != 0) { int carry = a & b; a = a ^ b; b = carry << 1; } return a; }
- Use stringbuilderIn place we can you swap to reverse, first reverse word, then reverse sentence