第一节课:同向双指针(主动指针,辅动指针)
第二节课:Union find: 数据的合并和元素的查找,老大哥节点
Trie: 字母树可以share公共前缀(没有儿子造儿子,有儿子沿着儿子往下走)
数据结构下:双堆(处理滑动窗口中位数,数据流中位数,求前k大的一个堆)
双端队列(求一段数里面最大的,如果一个数在之前比他小,就废掉了没有用)
单调stack(求一个数之前第一个比他大,比他小)
第四节课:二分答案:最大平均和子数组
扫描线:针对区间,区间开始区间结束,排序,有时加一有时减一,共享同一个y坐标的起点终点处理一下
第五节课dp:找到状态用最后一步,化成子问题,然后写dp方程,细心找到初始条件边界情况
滚动数组,只用前一行或者两行,用mod
划分型:最后一步,找最后一段
博弈:必胜态,必败态,必胜下面只要有一个必败就行
必败下面全是必胜
区间型:砍头去尾,二分first balloon
Dp下:双序列:看两个序列尾巴是否匹配
背包:最大总承重m放到dp里面去
Follow up: Iterator, SubarraySum, Wiggle Sort

Iterator

453. Flatten Binary Tree to Linked List

注意要freepointer
把右子树都接到左子树的最右,然后进行递归

  1. class Solution {
  2. public:
  3. /**
  4. * @param root: a TreeNode, the root of the binary tree
  5. * @return: nothing
  6. */
  7. void flatten(TreeNode * root) {
  8. // write your code here
  9. if (root == NULL){
  10. return;
  11. }
  12. if (root -> left){
  13. TreeNode* temp = root -> left;
  14. while(temp -> right != NULL){
  15. temp = temp-> right;
  16. }
  17. temp -> right = root -> right;
  18. root -> right = root -> left;
  19. root -> left = NULL;
  20. }
  21. flatten(root -> right);
  22. }
  23. };

22. Flatten List(递归以及费递归写法)

递归写法
某一些项放在另外一项之后
res.insert(res.end(), temp.begin(), temp.end());

  1. class Solution {
  2. public:
  3. // @param nestedList a list of NestedInteger
  4. // @return a list of integer
  5. vector<int> flatten(vector<NestedInteger> &nestedList) {
  6. // Write your code here
  7. vector <int> res;
  8. NestedInteger n;
  9. for(int i = 0; i < nestedList.size(); i ++){
  10. if (nestedList[i].isInteger()){
  11. res.push_back(nestedList[i].getInteger());
  12. }else{
  13. vector<NestedInteger> sub_list = nestedList[i].getList();
  14. vector<int> temp = flatten(sub_list);
  15. //vector<int> temp = flatten(nestedList[i].getList());
  16. res.insert(res.end(), temp.begin(), temp.end());
  17. }
  18. }
  19. return res;
  20. }
  21. };

非递归写法
非递归写法中,因为stack是先入后出,所以要先反向。

  1. class Solution {
  2. public:
  3. // @param nestedList a list of NestedInteger
  4. // @return a list of integer
  5. vector<int> flatten(vector<NestedInteger> &nestedList) {
  6. // Write your code here
  7. stack <NestedInteger> stk;
  8. for(int i = 0; i < nestedList.size(); i++){
  9. stk.push(nestedList[i]);
  10. }
  11. vector<int> res;
  12. while(stk.size() > 0){
  13. NestedInteger top = stk.top();
  14. stk.pop();
  15. if (top.isInteger()){
  16. res.push_back(top.getInteger());
  17. }else{
  18. vector<NestedInteger> temp = top.getList();
  19. for (int i = temp.size() - 1; i >= 0; i --){
  20. stk.push(temp[i]);
  21. }
  22. }
  23. }
  24. return res;
  25. }
  26. };

528. Flatten Nested List Iterator

  1. class NestedIterator {
  2. public:
  3. stack <NestedInteger> stk;
  4. NestedIterator(vector<NestedInteger> &nestedList) {
  5. // Initialize your data structure here.
  6. for(int i = nestedList.size() - 1; i >= 0; i --){
  7. stk.push(nestedList[i]);
  8. }
  9. }
  10. // @return {int} the next element in the iteration
  11. int next() {
  12. // Write your code here
  13. int ans = stk.top().getInteger();
  14. stk.pop();
  15. return ans;
  16. }
  17. // @return {boolean} true if the iteration has more element or false
  18. bool hasNext() {
  19. // Write your code here
  20. while (!stk.empty()){
  21. NestedInteger temp = stk.top();
  22. if(temp.isInteger()){
  23. return true;
  24. }else{
  25. stk.pop();
  26. vector<NestedInteger> tempNew = temp.getList();
  27. for(int i = tempNew.size() - 1; i >= 0; i --){
  28. stk.push(tempNew[i]);
  29. }
  30. }
  31. }
  32. return false;
  33. }
  34. };

Subarray Sum 前缀和问题

138. Subarray Sum

class Solution {
public:
    /**
     * @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
     */
    vector<int> subarraySum(vector<int> &nums) {
        // write your code here
        vector <int> prefixSum(nums.size() + 1, 0);
        int sum = 0; 
        unordered_map<int, int>pos;
        pos[0] = -1;
        vector <int> res;
        // if (nums[0] == 0){
        //     res =
        // }
        for (int i = 1; i < nums.size() + 1; i ++){
            sum += nums[i - 1];
            prefixSum[i] = sum;
            if(pos.find(sum) != pos.end()){
                res = {pos[sum] + 1, i - 1};
                return res;
            }else{
                pos[sum] = i - 1;
            }
        }
        return res;
    }
};

405. Submatrix Sum(二维的前缀和,时间复杂度O3)

在横向利用搜索和的方法,得到一个字典存进去和
字典可以用???。count() >0来判断key是否在自店内

class Solution {
public:
    /*
     * @param matrix: an integer matrix
     * @return: the coordinate of the left-up and right-down number
     */
    vector<vector<int>> submatrixSum(vector<vector<int>> &matrix) {
        // write your code here
        int m = matrix.size();
        int n = matrix[0].size();
        vector<vector<int>> res;
        vector<vector<int>> sum(m + 1, vector<int>(n + 1, 0));
        for (int i = 1; i < m + 1; i++)
            for (int j = 1; j < n + 1; j++)
                sum[i][j] += sum[i-1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + matrix[i - 1][j - 1];
        for (int i = 0; i < m; i ++){
            int sumtemp = 0;
            for (int j = i + 1; j < m + 1; j ++){
                unordered_map <int, int>check_res;
                check_res[0] = 0;
                for (int k = 1; k < n + 1; k ++){
                    sumtemp = sum[j][k] - sum[i][k];
                    if (check_res.count(sumtemp) > 0){
                        res = {{i, check_res[sumtemp]}, {j - 1, k - 1}};
                        return res;
                    }else{
                        check_res[sumtemp] = k;
                    }
                }
            }
        }
        return res;
    }
};

404. Subarray Sum II(两根指针,因为和全为正数)

写for循环的时候, i是前一个位置,j是最后的位置

public:
    /**
     * @param A: An integer array
     * @param start: An integer
     * @param end: An integer
     * @return: the number of possible answer
     */
    int subarraySumII(vector<int> &A, int start, int end) {
        // write your code here
        int m = A.size();
        int res = 0;
        vector<int> preSum(m + 1, 0);
        for(int i = 1; i < m + 1; i ++){
            preSum[i] = preSum[i - 1] + A[i - 1];
        }
        for (int i = 0; i < m; i ++){
            for (int j = i + 1; j < m + 1; j ++){
                if(preSum[j] - preSum[i] >= start && preSum[j] - preSum[i] <= end){
                    res ++;
                }
            }
        }
        return res;
    }
};

399. Nuts & Bolts Problem(排序,相互二分,二分的变形)

class Solution {
public:
    /**
     * @param nuts: a vector of integers
     * @param bolts: a vector of integers
     * @param compare: a instance of Comparator
     * @return: nothing
     */
    void sortNutsAndBolts(vector<string> &nuts, vector<string> &bolts, Comparator compare) {
        quickSort(nuts, bolts, 0, nuts.size()-1, compare);
    }
    void quickSort(vector<string> & nuts, vector<string> & bolts, int l, int r, Comparator compare){
        if (l >= r){
            return;
        }
        string pivot = nuts[l];
        int cnt = 0, pos = 0;
        for (int i = l; i <= r; i ++){
            int t = compare.cmp(pivot, bolts[i]);
            if (t == 1){
                cnt ++;
            }else if(t == 0){
                pos = i;
            }

        }
        cnt += l;
        swap(bolts[pos], bolts[cnt]);
        pos = cnt;
        for (int i = l, j = r; i < pos && pos < j;){
            while(i < pos && compare.cmp(pivot, bolts[i]) == 1)
                i++;
            while(pos < j && compare.cmp(pivot, bolts[j]) == -1)
                j--;
            if (i < pos && pos < j){
                swap(bolts[i++], bolts[j--]);
            }
        } 
        pivot = bolts[pos];
        swap(nuts[pos], nuts[l]);
        for (int i = l, j = r; i < pos && pos < j; )
        {
            while (i < pos && compare.cmp(nuts[i], pivot) == -1)
                i++;
            while (pos < j && compare.cmp(nuts[j], pivot) == 1)
                j--;
            if (i < pos && pos < j)
                swap(nuts[i++], nuts[j--]);
        }
        quickSort(nuts, bolts, l, pos - 1, compare);
        quickSort(nuts, bolts, pos + 1, r, compare);
    }
};

402. Continuous Subarray Sum(找最大子数组,O(n))

如果之前的数组比0小,就不再看,res从头开始
如果currsum比maxsum大,更新区间和maxsum

class Solution {
public:
    /*
     * @param A: An integer array
     * @return: A list of integers includes the index of the first number and the index of the last number
     */
    vector<int> continuousSubarraySum(vector<int> &A) {
        // write your code here
        int currSum = 0;
        int tempFirst = 0;
        int maxSum = INT_MIN;
        vector<int> res(2);
        for(int i = 0; i < A.size(); i ++){
            if (currSum >= 0){
                currSum += A[i];
            }else{
                currSum = A[i];
                tempFirst = i;
            }
            if (currSum > maxSum){
                res[0] = tempFirst;
                res[1] = i;
                maxSum = currSum;
            }

        } 
        return res;
    }
};

403. Continuous Subarray Sum II(环形问题)

找到数组中最大和和最小和的subarray, 互补思想,环形问题

class Solution {
public:
    /*
     * @param A: An integer array
     * @return: A list of integers includes the index of the first number and the index of the last number
     */
    vector<int> continuousSubarraySumII(vector<int> &A) {
        // write your code here
        vector<int> res(2, 0);
        int tempRes = 0;
        int maxRes = INT_MIN;
        int minRes = INT_MAX;
        int start = 0, end = 0, sum = 0;
        for (int i = 0; i < A.size(); i ++){
            sum += A[i];
            if(tempRes < 0){
                start = end;
                tempRes = 0;
            }
            tempRes += A[end];
            if (tempRes > maxRes){
                maxRes = tempRes;
                res[0] = start;
                res[1] = end;
            }
            end ++;
            cout << start <<' ' <<end << ' '<< maxRes<< endl;
        }
        start = 0;
        end = 0;
        tempRes = 0;
        for(int i = 0; i < A.size() - 1; i ++){
            if(tempRes > 0){
                start = end;
                tempRes = 0;
            }
            tempRes += A[end];
            if (tempRes < minRes){


                minRes = tempRes;
                // cout << start <<' ' <<end << ' '<< sum<< endl;
                // cout << maxRes<< ' ' << minRes <<  endl;
                // cout << sum - minRes << endl;
                if (sum - minRes > maxRes){
                    res[0] = end + 1;
                    res[1] = start - 1;
                }
            }
            end ++;
        }
        return res;
    }
};

558. Sliding Window Matrix Maximum(二维)

class Solution {
public:
    /**
     * @param matrix an integer array of n * m matrix
     * @param k an integer
     * @return the maximum number
     */
    int maxSlidingWindow2(vector<vector<int>>& matrix, int k) {
        // Write your code here
        int n = matrix.size();
        if (n == 0 || n < k)
            return 0;
        int m = matrix[0].size();
        if (m == 0 || m < k)
            return 0;

        vector<vector<int>> sum(n + 1, vector<int>(m + 1));
        for (int i = 0; i <= n; ++i) sum[i][0] = 0;
        for (int i = 0; i <= m; ++i) sum[0][i] = 0;

        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j)
                sum[i][j] = matrix[i - 1][j - 1] + 
                            sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];

        int max_value = INT_MIN;
        for (int i = k; i <= n; ++i)
            for (int j = k; j <= m; ++j) {
                int value = sum[i][j] - sum[i - k][j] -
                            sum[i][j - k] + sum[i - k][j - k];

                if (value > max_value)
                    max_value = value;
            }
        return max_value;
    }
};