九章算法高級班筆記7.Follow Up Question

Overview: cs3k.com 

  1. Subarray sum 3 follow up
  2. Continuous Subarray Sum 2 follow up
  3. Wiggle Sort 2 follow up
  4. Partition 3 follow up
  5. Iterator 3 follow up

Subarray Sum

cs3k.com 

Given an integer array, find a subarray where the sum of numbers is zero. Your code should return the index of the first number and the index of the last number.java

Noticenode

There is at least one subarray that it’s sum equals to zero.c++

Have you met this question in a real interview? Yes
Example
Given [-3, 1, 2, -3, 4], return [0, 2] or [1, 3].
數組

public class Solution { /** * @param nums: A list of integers * @return: A list of integers includes the index of the first number * and the index of the last number */ public ArrayList<Integer> subarraySum(int[] nums) { // write your code here int len = nums.length; ArrayList<Integer> ans = new ArrayList<Integer>(); HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); map.put(0, -1); int sum = 0; for (int i = 0; i < len; i++) { sum += nums[i]; if (map.containsKey(sum)) { ans.add(map.get(sum) + 1); ans.add(i); return ans; } map.put(sum, i); } return ans; } } 

Submatrix Sum

cs3k.com 

Given an integer matrix, find a submatrix where the sum of numbers is zero. Your code should return the coordinate of the left-up and right-down number.app

Example
Given matrixdom

[1 , 5 , 7]
  [3 , 7 ,-8]
  [4 ,-8 , 9]

return [(1,1), (2,2)]ide

能夠for循環暴力作函數

for lx = 0 ~ n
    for ly = 0 ~ n
        for rx = lx ~ n
            for ry = ly ~ n

時間複雜度是O(n^4)優化

接着咱們能夠想枚舉行, 對於ui

[1 , 5 , 7]
  [3 , 7 ,-8]
  [4 ,-8 , 9]

的第0行和第1行來講,咱們算出每列的sum:

[1 , 5 ,  7]
      [3 , 7 , -8]
  sum [4 , 12, -1]

而後咱們就把每一個列變成了一個列的和的值;
因此尋找二維的子矩陣就變成了尋找一維的子數組問題。

public class Solution { /** * @param matrix an integer matrix * @return the coordinate of the left-up and right-down number */ public int[][] submatrixSum(int[][] matrix) { int[][] result = new int[2][2]; int M = matrix.length; if (M == 0) return result; int N = matrix[0].length; if (N == 0) return result; // pre-compute: sum[i][j] = sum of submatrix [(0, 0), (i, j)] int[][] sum = new int[M+1][N+1]; for (int j=0; j<=N; ++j) sum[0][j] = 0; for (int i=1; i<=M; ++i) sum[i][0] = 0; for (int i=0; i<M; ++i) { for (int j=0; j<N; ++j) sum[i+1][j+1] = matrix[i][j] + sum[i+1][j] + sum[i][j+1] - sum[i][j]; } for (int l=0; l<M; ++l) { for (int h=l+1; h<=M; ++h) { Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (int j=0; j<=N; ++j) { int diff = sum[h][j] - sum[l][j]; if (map.containsKey(diff)) { int k = map.get(diff); result[0][0] = l; result[0][1] = k; result[1][0] = h-1; result[1][1] = j-1; return result; } else { map.put(diff, j); } } } } return result; } } 

Subarray Sum II

cs3k.com 

Given an integer array, find a subarray where the sum of numbers is in a given interval. Your code should return the number of possible answers. (The element in the array should be positive)
Example
Given [1,2,3,4] and interval = [1,3], return 4. The possible answers are:

[0, 0]
[0, 1]
[1, 1]
[2, 2]

對於數組,咱們須要計算一個presum數組:

[1,  2,  3,  4]
pre   [0,  1,  3,  6, 10]

若是一個子數組在1和3之間,就至關於咱們有了等式:

1 <= pre[j+1] - pre[i] <= 3

而後咱們能夠進行兩步:

1. for j = 0 ~ n
2. 找對應範圍內[pre[j+1]-3, pre[j+1]-1]曾經遍歷的個數

咱們能夠二分法優化, 找>=pre[j+1]-3的最小元素和小於等於pre[j+1]-1的最小元素,時間變成(n*logn)。

public class Solution { /** * @param A an integer array * @param start an integer * @param end an integer * @return the number of possible answer */ int find(int[] A, int len, int value) { if (A[len-1] < value ) return len; int l = 0, r = len-1, ans = 0; while (l <= r) { int mid = (l + r) / 2; if (value <= A[mid]) { ans = mid; r = mid - 1; } else l = mid + 1; } return ans; } public int subarraySumII(int[] A, int start, int end) { // Write your code here int len = A.length; for (int i = 1; i <len; ++i) A[i] += A[i-1]; int cnt = 0; for (int i = 0; i <len; ++i) { if (A[i] >= start && A[i] <= end) cnt ++; int l = A[i] - end; int r = A[i] - start; cnt += find(A, len, r+1) - find(A, len, l); } return cnt; } } 

Continuous Subarray Sum

cs3k.com 

Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your code should return the index of the first number and the index of the last number. (If their are duplicate answer, return anyone)

Example
Give [-3, 1, 3, -3, 4], return [1,4].

public class Solution { /** * @param A an integer array * @return A list of integers includes the index of the first number and the index of the last number */ public ArrayList<Integer> continuousSubarraySum(int[] A) { // Write your code here ArrayList<Integer> result = new ArrayList<Integer>(); result.add(0); result.add(0); int len = A.length; int start = 0, end = 0; int sum = 0; int ans = -0x7fffffff; for (int i = 0; i < len; ++i) { if (sum < 0) { sum = A[i]; start = end = i; } else { sum += A[i]; end = i; } if (sum >= ans) { ans = sum; result.set(0, start); result.set(1, end); } } return result; } } 

Maximum Subarray

cs3k.com 

Given an array of integers, find a contiguous subarray which has the largest sum.

Notice

The subarray should contain at least one number.

Example
Given the array [−2,2,−3,4,−1,2,1,−5,3], the contiguous subarray [4,−1,2,1] has the largest sum = 6.

就是f[i]以i做爲結尾的子數組的和最大是多少, 對於每一個i都有兩種狀況,取和不取。

public class Solution { public int maxSubArray(int[] A) { if (A == null || A.length == 0){ return 0; } int max = Integer.MIN_VALUE, sum = 0; for (int i = 0; i < A.length; i++) { sum += A[i]; max = Math.max(max, sum); sum = Math.max(sum, 0); } return max; } } // Version 2: Prefix Sum public class Solution { public int maxSubArray(int[] A) { if (A == null || A.length == 0){ return 0; } int max = Integer.MIN_VALUE, sum = 0, minSum = 0; for (int i = 0; i < A.length; i++) { sum += A[i]; max = Math.max(max, sum - minSum); minSum = Math.min(minSum, sum); } return max; } } public class Solution { /** * @param nums: a list of integers * @return: A integer indicate the sum of minimum subarray */ public int maxSubArray(int[] nums) { // write your code if(nums.length == 0){ return 0; } int n = nums.length; int[] global = new int[2]; int[] local = new int[2]; global[0] = nums[0]; local[0] = nums[0]; for(int i = 1; i < n; i ++) { local[i % 2] = Math.max(nums[i], local[(i - 1) % 2] + nums[i]); global[i % 2] = Math.max(local[i % 2], global[(i - 1) % 2]); } return global[(n-1) % 2]; } } 

Continuous Subarray Sum II

cs3k.com 

Given an circular integer array (the next element of the last element is the first element), find a continuous subarray in it, where the sum of numbers is the biggest. Your code should return the index of the first number and the index of the last number.

If duplicate answers exist, return any of them.

Example
Give [3, 1, -100, -3, 4], return [4,1].

循環子數組的處理方式爲三種:

  1. 分裂
  2. 倍增
  3. 取反

這道題分裂貌似不太好分,倍增能夠作, 假如栗子是:

[-3,  1,  3,  -3,  4]

咱們把這個數組後面再接一個本身:

[-3,  1,  3,  -3,  4, -3,  1,  3,  -3,  4]

而後約束長度爲n, 找答案,能夠作,可是時間複雜度比較高, 是O(n^2).

還有一個作法就是取反,咱們不是求最大的連續子數組麼?
有兩種狀況:

|————————---|  max  |———————————|
             start     end

|     max   |-------|    max    |
              end     start

第一種狀況很容易, 第二種狀況呢, 由於整個數組的和是固定的,咱們要求兩邊數組的最大值, 就求中間區間的最小值就行了。

public class Solution { /** * @param A an integer array * @return A list of integers includes the index of the first number and the index of the last number */ public List<Integer> continuousSubarraySumII(int[] A) { // Write your code here List<Integer> result = new ArrayList<Integer>(); result.add(0); result.add(0); int total = 0; int len = A.length; int start = 0, end = 0; int local = 0; int global = -0x7fffffff; for (int i = 0; i < len; ++i) { total += A[i]; if (local < 0) { local = A[i]; start = end = i; } else { local += A[i]; end = i; } if (local >= global) { global = local; result.set(0, start); result.set(1, end); } } local = 0; start = 0; end = -1; for (int i = 0; i < len; ++i) { if (local > 0) { local = A[i]; start = end = i; } else { local += A[i]; end = i; } if (start == 0 && end == len-1) continue; if (total - local >= global) { global = total - local; result.set(0, (end + 1) % len); result.set(1, (start - 1 + len) % len); } } return result; } } 

Kth Largest Element

cs3k.com 

Find K-th largest element in an array.

Notice

You can swap elements in the array

Example
In array [9,3,2,4,8], the 3rd largest element is 4.

In array [1,2,3,4,5], the 1st largest element is 5, 2nd largest element is 4, 3rd largest element is 3 and etc.

  1. PriorityQueue
  • 時間複雜度O(nlogk)
  • 更適合Topk
  1. QuickSelect
  • 時間複雜度O(n)
  • 更適合第k大

partition問題模板
enter image description here

quick sort模板

import java.util.Random; public class Solution { /* * @param A: an integer array * @return: */ public Random rand; public void sortIntegers2(int[] A) { rand = new Random(); // write your code here quickSort(A, 0, A.length - 1); } public void quickSort(int[] A, int start, int end) { if (start >= end) { return; } int index = rand.nextInt(end - start + 1) + start; int pivot = A[index]; int left = start; int right = end; while (left <= right) { while (left <= right && A[left] < pivot) { left ++; } while (left <= right && A[right] > pivot) { right --; } if (left <= right) { int temp = A[left]; A[left] = A[right]; A[right] = temp; left ++; right --; } } // A[start... right] quickSort(A, start, right); // A[left ... end] quickSort(A, left, end); } }

merge sort:

public class Solution { /** * @param A an integer array * @return void */ public void sortIntegers2(int[] A) { // use a shared temp array, the extra memory is O(n) at least int[] temp = new int[A.length]; mergeSort(A, 0, A.length - 1, temp); } private void mergeSort(int[] A, int start, int end, int[] temp) { if (start >= end) { return; } int left = start, right = end; int mid = (start + end) / 2; mergeSort(A, start, mid, temp); mergeSort(A, mid+1, end, temp); merge(A, start, mid, end, temp); } private void merge(int[] A, int start, int mid, int end, int[] temp) { int left = start; int right = mid+1; int index = start; // merge two sorted subarrays in A to temp array while (left <= mid && right <= end) { if (A[left] < A[right]) { temp[index++] = A[left++]; } else { temp[index++] = A[right++]; } } while (left <= mid) { temp[index++] = A[left++]; } while (right <= end) { temp[index++] = A[right++]; } // copy temp back to A for (index = start; index <= end; index++) { A[index] = temp[index]; } } } 

 

class Solution { /* * @param k : description of k * @param nums : array of nums * @return: description of return */ public int kthLargestElement(int k, int[] nums) { // write your code here if (nums == null || nums.length == 0) { return 0; } if (k <= 0) { return 0; } return helper(nums, 0, nums.length - 1, nums.length - k + 1); } public int helper(int[] nums, int l, int r, int k) { if (l == r) { return nums[l]; } int position = partition(nums, l, r); if (position + 1 == k) { return nums[position]; } else if (position + 1 < k) { return helper(nums, position + 1, r, k); } else { return helper(nums, l, position - 1, k); } } public int partition(int[] nums, int l, int r) { // 初始化左右指針和pivot int left = l, right = r; int pivot = nums[left]; // 進行partition while (left < right) { while (left < right && nums[right] >= pivot) { right--; } nums[left] = nums[right]; while (left < right && nums[left] <= pivot) { left++; } nums[right] = nums[left]; } // 返還pivot點到數組裏面 nums[left] = pivot; return left; } }; class Solution { /* * @param k : description of k * @param nums : array of nums * @return: description of return */ public int kthLargestElement(int k, int[] nums) { // write your code here int low = 0, high = nums.length -1; while(low <= high){ int pivot = nums[high]; int index = low-1; for(int i = low; i < high; i++){ if(nums[i] > nums[high]){ swap(nums, i, ++index); } } swap(nums, ++index, high); if(index == k - 1){ return nums[index]; } if(index < k -1){ low = index + 1; }else{ high = index - 1; } } return -1; } private void swap(int[] nums, int a, int b){ int temp = nums[a]; nums[a] = nums[b]; nums[b] = temp; } }; 

quick select時間複雜度平均是O(2*n), 最壞可能達到O(n^2)
quick sort的時間平均是O(nlogn), 由於quick select分兩半以後是丟一半, 排一半。而quick sort是兩邊都要分別排序。quick sort最差也多是O(n^2)。

 

 

Wiggle Sort

cs3k.com 

Given an unsorted array nums, reorder it in-place such that

nums[0] <= nums[1] >= nums[2] <= nums[3]…

Please complete the problem in-place.
Example
Given nums = [3, 5, 2, 1, 6, 4], one possible answer is [1, 6, 2, 5, 3, 4].

public class Solution { /** * @param nums a list of integer * @return void */ public void wiggleSort(int[] nums) { // Write your code here for(int i=1; i<nums.length; i++) { if((i%2==1 && (nums[i] < nums[i-1]) || (i%2==0) && (nums[i] > nums[i-1]))) { swap(nums, i-1, i); } } } public void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } } 

Wiggle Sort II

cs3k.com 

Given an unsorted array nums, reorder it such that

nums[0] < nums[1] > nums[2] < nums[3]…
Notice

You may assume all input has valid answer.
Example
Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6].

Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2].

首先, 可能回想先排個序, 而後兩個指針取元素。
其次若是優化的話, 能夠partition找中位數, 而後左邊取一個, 右邊取一個。

public class Solution { public static void wiggleSort(int[] nums) { int[] tem = new int[nums.length]; for (int i = 0; i < nums.length; i++) { tem[i] = nums[i]; } int mid = partition(tem, 0, nums.length-1, nums.length/2); int[] ans = new int[nums.length]; for (int i = 0; i < nums.length; i++) { ans[i] = mid; } int l, r; if (nums.length % 2 == 0) { l = nums.length - 2; r = 1; for (int i = 0; i < nums.length; i++) { if (nums[i] < mid) { ans[l] = nums[i]; l -= 2; } else if (nums[i] > mid) { ans[r] = nums[i]; r += 2; } } } else { l = 0; r = nums.length - 2; for (int i = 0; i < nums.length; i++) { if (nums[i] < mid) { ans[l] = nums[i]; l += 2; } else if (nums[i] > mid) { ans[r] = nums[i]; r -= 2; } } } for (int i = 0; i < nums.length; i++) { nums[i] = ans[i]; } } public static int partition(int[] nums, int l, int r, int rank) { int left = l, right = r; int now = nums[left]; while (left < right) { while (left < right && nums[right] >= now) { right--; } nums[left] = nums[right]; while (left < right && nums[left] <= now) { left++; } nums[right] = nums[left]; } if (left - l == rank) { return now; } else if (left - l < rank) { return partition(nums, left + 1, r, rank - (left - l + 1)); } else { return partition(nums, l, right - 1, rank); } } }

Nuts & Bolts Problem

Given a set of n nuts of different sizes and n bolts of different sizes. There is a one-one mapping between nuts and bolts. Comparison of a nut to another nut or a bolt to another bolt is not allowed. It means nut can only be compared with bolt and bolt can only be compared with nut to see which one is bigger/smaller.

We will give you a compare function to compare nut with bolt.
Example
Given nuts = [‘ab’,‘bc’,‘dd’,‘gg’], bolts = [‘AB’,‘GG’, ‘DD’, ‘BC’].

Your code should find the matching bolts and nuts.

one of the possible return:

nuts = [‘ab’,‘bc’,‘dd’,‘gg’], bolts = [‘AB’,‘BC’,‘DD’,‘GG’].

we will tell you the match compare function. If we give you another compare function.

the possible return is the following:

nuts = [‘ab’,‘bc’,‘dd’,‘gg’], bolts = [‘BC’,‘AA’,‘DD’,‘GG’].

So you must use the compare function that we give to do the sorting.

The order of the nuts or bolts does not matter. You just need to find the matching bolt for each nut.

用nuts給bolts來partition, 再用bolts給nuts來partition.

public class Solution { /** * @param nuts: an array of integers * @param bolts: an array of integers * @param compare: a instance of Comparator * @return: nothing */ public void sortNutsAndBolts(String[] nuts, String[] bolts, NBComparator compare) { if (nuts == null || bolts == null) return; if (nuts.length != bolts.length) return; qsort(nuts, bolts, compare, 0, nuts.length - 1); } private void qsort(String[] nuts, String[] bolts, NBComparator compare, int l, int u) { if (l >= u) return; // find the partition index for nuts with bolts[l] int part_inx = partition(nuts, bolts[l], compare, l, u); // partition bolts with nuts[part_inx] partition(bolts, nuts[part_inx], compare, l, u); // qsort recursively qsort(nuts, bolts, compare, l, part_inx - 1); qsort(nuts, bolts, compare, part_inx + 1, u); } private int partition(String[] str, String pivot, NBComparator compare, int l, int u) { for (int i = l; i <= u; i++) { if (compare.cmp(str[i], pivot) == 0 || compare.cmp(pivot, str[i]) == 0) { swap(str, i, l); break; } } String now = str[l]; int left = l; int right = u; while (left < right) { while (left < right && (compare.cmp(str[right], pivot) == -1 || compare.cmp(pivot, str[right]) == 1)) { right--; } str[left] = str[right]; while (left < right && (compare.cmp(str[left], pivot) == 1 || compare.cmp(pivot, str[left]) == -1)) { left++; } str[right] = str[left]; } str[left] = now; return left; } private void swap(String[] str, int l, int r) { String temp = str[l]; str[l] = str[r]; str[r] = temp; } } 

Flatten List

cs3k.com 

Given a list, each element in the list can be a list or integer. flatten it into a simply list with integers.

Notice

If the element in the given list is a list, it can contain list too.

Example
Given [1,2,[1,2]], return [1,2,1,2].

Given [4,[3,[2,[1]]]], return [4,3,2,1].

遞歸來解。

plus:c++ vector的reverse時間複雜度是O(n), 對稱位置swap來作。

public class Solution { // @param nestedList a list of NestedInteger // @return a list of integer public List<Integer> flatten(List<NestedInteger> nestedList) { // Write your code here List<Integer> result = new ArrayList<Integer>(); for (NestedInteger ele : nestedList) if (ele.isInteger()) result.add(ele.getInteger()); else result.addAll(flatten(ele.getList())); return result; } } //non-recursive version public class Solution { // @param nestedList a list of NestedInteger // @return a list of integer public List<Integer> flatten(List<NestedInteger> nestedList) { boolean isFlat = true; List<NestedInteger> ls = nestedList; while (isFlat) { isFlat = false; List<NestedInteger> newLs = new ArrayList<>(); for (NestedInteger ni : ls) { if (ni.isInteger()) { newLs.add(ni); } else { newLs.addAll(ni.getList()); isFlat = true; } } ls = newLs; } List<Integer> r = new ArrayList<>(); for (NestedInteger ni : ls) { r.add(ni.getInteger()); } return r; } } 

Flatten Nested List Iterator

cs3k.com 

Given a nested list of integers, implement an iterator to flatten it.

Each element is either an integer, or a list – whose elements may also be integers or other lists.

Notice

You don’t need to implement the remove method.

Example
Given the list [[1,1],2,[1,1]], By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1].

Given the list [1,[4,[6]]], By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6].

能夠用遞歸來解。iterator和遞歸比起來,有個好處。是遞歸的時候,你中間不能作其它事情,而iterator用非遞歸的方式來實現,能夠被打斷。
這道題,不能預先存下來,而後再用個指針。由於iterator的意義是不到打印或者其它用的時候,不遍歷。
解法就是用棧,思路不難,寫法麻煩點:

  1. next函數本身要調用hasNext
  2. 棧的處理放在hasNext裏面好一些

Iterator要點

cs3k.com 

  1. List 轉 Stack
  2. 主函數邏輯放在HasNext裏面
  3. Next只作一次pop處理

模板:

enter image description here

import java.util.Iterator; public class NestedIterator implements Iterator<Integer> { private Stack<NestedInteger> stack; private void pushListToStack(List<NestedInteger> nestedList) { Stack<NestedInteger> temp = new Stack<>(); for (NestedInteger nested : nestedList) { temp.push(nested); } while (!temp.isEmpty()) { stack.push(temp.pop()); } } public NestedIterator(List<NestedInteger> nestedList) { stack = new Stack<>(); pushListToStack(nestedList); } // @return {int} the next element in the iteration @Override public Integer next() { if (!hasNext()) { return null; } return stack.pop().getInteger(); } // @return {boolean} true if the iteration has more element or false @Override public boolean hasNext() { while (!stack.isEmpty() && !stack.peek().isInteger()) { pushListToStack(stack.pop().getList()); } return !stack.isEmpty(); } @Override public void remove() {} } 

Flatten 2D Vector

cs3k.com 

Implement an iterator to flatten a 2d vector.

Example
Given 2d vector =

[1,2],
  [3],
  [4,5,6]

By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,2,3,4,5,6].

和上一道題相似,用棧。

public class Vector2D implements Iterator<Integer> { Stack<List<Integer>> stack = new Stack<>(); Stack<Integer> stackj; void pushListListToStack(List<List<Integer>> vec2d) { Stack<List<Integer>> temp = new Stack<>(); for (List<Integer> nested : vec2d) { temp.push(nested); } while (!temp.isEmpty()) { stack.push(temp.pop()); } } void pushListToStack(List<Integer> vec) { Stack<Integer> temp = new Stack<>(); for (Integer nested : vec) { temp.push(nested); } while (!temp.isEmpty()) { stackj.push(temp.pop()); } } public Vector2D(List<List<Integer>> vec2d) { pushListListToStack(vec2d); // Initialize your data structure here stackj = new Stack<>(); } public Integer next() { // Write your code here if(!hasNext()) { return null; } return stackj.pop(); } public boolean hasNext() { // 準備下一個元素 // Write your code here while (stackj.isEmpty() && !stack.isEmpty()) pushListToStack(stack.pop()); return !stackj.isEmpty(); } public void remove() {} } 

Binary Search Tree Iterator

cs3k.com 

Design an iterator over a binary search tree with the following rules:

Elements are visited in ascending order (i.e. an in-order traversal)
next() and hasNext() queries run in O(1) time in average.

Example
For the following binary search tree, in-order traversal by using iterator is [1, 6, 10, 11, 12]

10
 /    \
1      11
 \       \
  6       12

把節點和節點全部的左兒子加入棧裏面。
時間複雜度平攤是O(n)

public class BSTIterator { private Stack<TreeNode> stack = new Stack<>(); TreeNode next = null; void AddNodeToStack(TreeNode root) { while (root != null) { stack.push(root); root = root.left; } } // @param root: The root of binary tree. public BSTIterator(TreeNode root) { next = root; } //@return: True if there has next node, or false public boolean hasNext() { if (next != null) { AddNodeToStack(next); next = null; } return !stack.isEmpty(); } //@return: return next node public TreeNode next() { if (!hasNext()) { return null; } TreeNode cur = stack.pop(); next = cur.right; return cur; } } 

Follow Up 常見方式

cs3k.com 

  1. 一維轉二維
  • 能夠套相同的思路試一試
    • Find Peak Element I/II
    • Trapping Water I/II
    • Subarray Sum/Submatrix Sum
  1. 數組變成循環數組
  • 循環數組小技巧: 分裂 倍增 取反
    • Continuous Subarray Sum
  1. 題目條件增強
  • 可能題目的解題方法會變化,若是全部條件都不變,就一個條件變了,那基本要從新分析,不能套老方法。
    • Wiggle Sort I/II
  1. 換馬甲(變一個描述,本質不變)
  • 本質不變
    • Number of airplane on the Sky/ Meeting Room
    • BackPack Problem
  1. 描述徹底不同,可是方法相同
  • 這種題目得去分析
    • 前向型指針的題目
    • Quick Sort/ Bolt Nuts Problem
相關文章
相關標籤/搜索