Hot 100 Rec

from LeetCode Hot100 and CodeTop

文章目录

3. 无重复字符的最长子串

3. 无重复字符的最长子串
for + while 版的双指针代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size() == 0 || s.size() == 1) return s.size();
        int n = s.size(), ret = 1;
        unordered_map<int, int> umap;

        for (int i = 0, j = 0; i < n; i ++) {
            while (j < n && umap[s[j]] == 0) {
                umap[s[j++]] ++;
                ret = max(ret, j - i);
            }
            umap[s[i]] --;
        }

        return ret;
    }
};

206. 反转链表

206. 反转链表

  1. 迭代
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* ret = NULL;
        while(head) {
            ListNode* tmp = head -> next;
            head -> next = ret;
            ret = head;
            head = tmp;
        }
        return ret;
    }
};
  1. 递归
class Solution {
public:
    ListNode* rever(ListNode* head, ListNode* tmp) {
        if(!head) return tmp;

        ListNode* curr = head -> next;
        head -> next = tmp;
        return rever(curr, head);
    }

    ListNode* reverseList(ListNode* head) {
        return rever(head, NULL);
    }
};

146. LRU缓存机制

146. LRU缓存机制

class LRUCache {
public:
    // 定义双链表
    struct Node {
        int key, value;
        Node* left, *right;
        Node(int _key, int _value) : key(_key), value(_value), left(NULL), right(NULL) {}
    }*L, *R;
    int n;
    unordered_map<int, Node*> umap;   

    LRUCache(int capacity) {
        n = capacity;
        L = new Node(-1, -1);
        R = new Node(-1, -1);
        L -> right = R;
        R -> left = L;
    }
    
    int get(int key) {
        if (umap.count(key) == 0) return -1;
        auto p = umap[key];
        remove(p);
        insert(p);
        return p->value;
    }
    
    void put(int key, int value) {
        if (umap.count(key)) {
            auto p = umap[key];
            p -> value = value;
            remove(p);
            insert(p);
        } else {
            if (umap.size() == n) {
                auto p = R -> left;
                remove(p);
                umap.erase(p->key);
                delete p;
            }
            auto p = new Node(key, value);
            umap[key] = p;
            insert(p);
        }
    }

    void remove(Node* p) {
        p->left->right = p->right;
        p->right->left = p->left;
    }

    void insert(Node* p) {
        L->right->left = p;
        p->right = L->right;
        p->left = L;
        L->right = p;
    }
};

215. 数组中的第K个最大元素

215. 数组中的第K个最大元素

class Solution {
public:
    int target;

    int quickSort(vector<int>& nums, int left, int right) {
        if (left == right) return nums[left];

        int i = left - 1, j = right + 1, q = nums[left + right >> 1];
        while(i < j) {
            do i ++; while(nums[i] < q);
            do j --; while(nums[j] > q);
            if(i < j) swap(nums[i], nums[j]);
        }
        if(j >= target) return quickSort(nums, left, j);
        else return quickSort(nums, j + 1, right);
    }

    int findKthLargest(vector<int>& nums, int k) {
        target = nums.size() - k;
        return quickSort(nums, 0, nums.size() - 1);
    }
};

25. K 个一组翻转链表

class Solution {
public:
    void reverse(ListNode* preleft, int t) {
        ListNode* end = preleft;
        for(int i = 0; i < t; i ++) {
            end = end -> next;
        }
        
        ListNode* curr = preleft -> next;
        preleft -> next = end -> next;
        
        for(int i = 0; i < t; i ++) {
            ListNode* tmp = curr -> next;
            curr -> next = preleft -> next;
            preleft -> next = curr;
            curr = tmp;
        }
    }

    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* p = head;
        ListNode* hair = new ListNode(0);
        hair -> next = head;
        ListNode* preleft = hair;
        int cnt = 0;
        while(p) {
            cnt ++;
            if (cnt == k) {
                reverse(preleft, k);
                for(int i = 0; i < k - 1; i ++){
                    p = p -> next;
                }
                preleft = p;
                cnt = 0;
            } p = p -> next;
        }
        return hair -> next;
    }
};

15. 三数之和

15. 三数之和

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ret;
        int n = nums.size();
        if (n < 3) return ret;
        sort(nums.begin(), nums.end());

        for (int i = 0; i < n - 2; i ++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;

            int l = i + 1, r = n - 1; 
            while (l < r) {
                if (nums[i] + nums[l] + nums[r] < 0) l ++;
                else if (nums[i] + nums[l] + nums[r] > 0)  r--;
                else {
                    ret.push_back({nums[i], nums[l], nums[r]});

                    while(l < r && nums[r] == nums[r - 1]) r --;
                    while(l < r && nums[l] == nums[l + 1]) l ++;
                    l ++, r --;
                }
            }
        }

        return ret;
    }
};

53. 最大子序和

53. 最大子序和

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int pre=0, ret=-1e6;
        for(int i=0; i<nums.size(); i++) {
            pre = max(pre+nums[i], nums[i]);
            ret = max(ret, pre);
        }
        return ret;
    }
};

补充题4. 手撕快速排序

补充题4. 手撕快速排序

class Solution {
public:
    void quick_sort(vector<int>& q, int left, int right)
    {
        if (left >= right) return;

        int mid = rand()%(right - left + 1) + left;
        int i = left - 1, j = right + 1, x = q[mid];
        while (i < j)
        {
            do i ++ ; while (q[i] < x);
            do j -- ; while (q[j] > x);
            if (i < j) swap(q[i], q[j]);
        }
        quick_sort(q, left, j), quick_sort(q, j + 1, right);
    }
    
    vector<int> sortArray(vector<int>& nums) {
        srand(time(0));
        quick_sort(nums, 0, nums.size() - 1);
        return nums;
    }
};

21. 合并两个有序链表

21. 合并两个有序链表

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if(!list1 || !list2) return !list1 ? list2 : list1;

        ListNode* head = new ListNode(0);
        ListNode* h = head;
        while(list1 && list2) {
            if (list1 -> val < list2 -> val) {
                h -> next = list1;
                list1 = list1 -> next;
            } else {
                h -> next = list2;
                list2 = list2 -> next;
            }
            h = h -> next;
        }
        if (list1) h -> next = list1;
        if (list2) h -> next = list2;

        return head -> next;
    }
};

1. 两数之和

1. 两数之和

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> umap;
        for(int i =0; i < nums.size(); i ++){
            auto f = umap.find(target - nums[i]);
            if(f!=umap.end()) {
                return {f->second, i};
            }
            umap[nums[i]] = i;
        }
        return {};
    }
};

102. 二叉树的层序遍历

102. 二叉树的层序遍历

class Solution {
public:
    vector<vector<int>> ret;

    void dfs(TreeNode* root, int level) {
        if (!root) return;
        
        if (ret.size() < level) {
            ret.push_back({root -> val});
        } else {
            ret[level - 1].push_back({root -> val});
        }

        if(root -> left) dfs(root -> left, level + 1);
        if(root -> right) dfs(root -> right, level + 1);
    }

    vector<vector<int>> levelOrder(TreeNode* root) {
        dfs(root, 1);
        return ret;
    }
};

33. 搜索旋转排序数组

33. 搜索旋转排序数组

class Solution {
public:
    int search(vector<int>& nums, int target) {        
        int left = 0, right = nums.size() - 1;
        while(left < right) {
            int mid = left + right >> 1;
            if (nums[left] == target) return left;
            else if (nums[right] == target) return right;
            else if (nums[mid] == target) return mid;
            else if (nums[left] < nums[mid]) {
                if (nums[mid] > target && nums[left] < target) right = mid;
                else left = mid + 1;
            } else {
                if (nums[mid] < target && nums[left] > target) left = mid + 1;
                else right = mid;
            }
        }
        if (nums[left] == target) return left;

        return -1;
    }
};

5. 最长回文子串

5. 最长回文子串

class Solution {
public:
    string longestPalindrome(string s) {
        int ret = 1;
        if (s.size() == 1) return s;

        int left, right;
        pair<int, int> loc;
        for (int i = 0; i < s.size() - 1; i ++) {
            left = i - 1, right = i + 1;
            while(left >= 0 && right < s.size() && s[left] == s[right]) {
                if (right - left + 1 > ret) {
                    loc.first = left, loc.second = right;
                    ret = right - left + 1;
                }
                left --;
                right ++;
            }

            left = i, right = i + 1;
            while(left >= 0 && right < s.size() && s[left] == s[right]) {
                if (right - left + 1 > ret) {
                    loc.first = left, loc.second = right;
                    ret = right - left + 1;
                }
                left --;
                right ++;
            }
        }

        return ret == 1 ? s.substr(0, 1) : s.substr(loc.first, loc.second - loc.first + 1);
    }
};

20. 有效的括号

20. 有效的括号

class Solution {
public:
    bool isValid(string s) {
        if (s.size() < 2) return false;
        stack<int> stk;
        while(!stk.empty()) stk.pop();
        for (int i = 0; i < s.size(); i ++) {
            if (s[i] == ')') {
                if (!stk.empty() && stk.top() == '(') stk.pop();
                else return false;
            } 
            else if (s[i] == ']') {
                if (!stk.empty() && stk.top() == '[') stk.pop();
                else return false;
            } 
            else if (s[i] == '}') {
                if (!stk.empty() && stk.top() == '{') stk.pop();
                else return false;
            } 
            else stk.push(s[i]);
        }
        if (stk.empty()) return true;
        else return false;
    }
};

121. 买卖股票的最佳时机

121. 买卖股票的最佳时机

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size(), tmp = prices[n - 1], ret = 0;
        for (int i = n - 2; i >= 0; i --) {
            tmp = max(tmp, prices[i + 1]);
            ret = max(ret, tmp - prices[i]);
        }
        return ret;
    }
};

141. 环形链表

141. 环形链表

class Solution {
public:
    bool hasCycle(ListNode *head) {
        if (!head || !head -> next) return false;
        ListNode* slow = head, *fast = head;
        while (fast && fast -> next) {
            slow = slow -> next, fast = fast -> next -> next;
            if (slow == fast) return true;
        }
        return false;
    }
};

88. 合并两个有序数组

88. 合并两个有序数组

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int p = m + n, p1 = m - 1, p2 = n - 1;
        while(p --) {
            if (p1 >= 0 && p2 >= 0) {
                if (nums1[p1] >= nums2[p2]) nums1[p] = nums1[p1 --];
                else nums1[p] = nums2[p2 --];
            } else if (p1 >= 0) nums1[p] = nums1[p1 --];
            else nums1[p] = nums2[p2 --];
        }
    }
};

200. 岛屿数量

200. 岛屿数量

class Solution {
public:
    void dfs (vector<vector<char>>& grid, int x, int y, int from) {
        if (grid[x][y] != '1') return;
        grid[x][y] = '0';
        if (from != 2 && y + 1 < grid[0].size() && grid[x][y + 1] == '1') dfs(grid, x, y + 1, 4);
        if (from != 3 && x + 1 < grid.size() && grid[x + 1][y] == '1') dfs(grid, x + 1, y, 1);
        if (from != 4 && y - 1 >= 0 && grid[x][y - 1] == '1') dfs(grid, x, y - 1, 2);
        if (from != 1 && x - 1 >= 0 && grid[x - 1][y] == '1') dfs(grid, x - 1, y, 3);
    }

    int numIslands(vector<vector<char>>& grid) {
        int cnt = 0;

        for (int i = 0; i < grid.size(); i ++) {
            for (int j = 0; j < grid[0].size(); j ++) {
                if (grid[i][j] == '1') {
                    dfs(grid, i, j, -1);
                    cnt += 1;
                }
            }
        }

        return cnt;
    }
};

236. 二叉树的最近公共祖先

236. 二叉树的最近公共祖先

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == p || root == q || root == NULL) return root;
        TreeNode* left = lowestCommonAncestor(root -> left, p, q);
        TreeNode* right = lowestCommonAncestor(root -> right, p, q);
        if(left != NULL && right != NULL) return root;
        else if (left != NULL) return left;
        else return right; 
    }
};

103. 二叉树的锯齿形层次遍历

103. 二叉树的锯齿形层次遍历

class Solution {
public:
    vector<vector<int>> ret;

    void dfs(TreeNode* root, int level) {
        if (!root) return;
        if (ret.size() < level) ret.push_back({root -> val});
        else if (level % 2 == 1) ret[level - 1].push_back(root -> val);
        else ret[level - 1].insert(ret[level - 1].begin(), root -> val);
        if(root -> left) dfs(root -> left, level + 1);
        if(root -> right) dfs(root -> right, level + 1);
    }

    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        dfs(root, 1);
        return ret;
    }
};

46. 全排列

46. 全排列

class Solution {
public:
    vector<vector<int>> ret;

    void fulllist(vector<vector<int>>& ret, vector<int>& nums, int idx, int len) {
        if (len == idx) {
            ret.push_back(nums);
            return;
        }

        for (int i = idx; i < len; i ++) {
            swap(nums[i], nums[idx]);
            fulllist(ret, nums, idx + 1, nums.size());
            swap(nums[i], nums[idx]);
        }
    }

    vector<vector<int>> permute(vector<int>& nums) {
        if (nums.size() == 1) return {nums};
        fulllist(ret, nums, 0, nums.size());
        return ret;
    }
};

54. 螺旋矩阵

54. 螺旋矩阵

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> ret;
        if (matrix.empty()) return ret;

        int left = 0, right = matrix[0].size() - 1;
        int top = 0, bot = matrix.size() - 1;

        while(true) {
            for(int i = left; i <= right; i ++) ret.emplace_back(matrix[top][i]);
            if (++ top > bot) break;
            for(int i = top; i <= bot; i ++) ret.emplace_back(matrix[i][right]);
            if (-- right < left) break;
            for(int i = right; i >= left; i --) ret.emplace_back(matrix[bot][i]);
            if (-- bot < top) break;
            for(int i = bot; i >= top; i --) ret.emplace_back(matrix[i][left]);
            if (++ left > right) break;
        }

        return ret;
    }
};

160. 相交链表

160. 相交链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* tmpA = headA, *tmpB = headB;
        int lenA = 0, lenB = 0;
        while(tmpA && tmpB) {
            lenA ++;
            lenB ++;
            tmpA = tmpA -> next;
            tmpB = tmpB -> next;
        }
        if (tmpA) {
            while(tmpA) {
                lenA ++;
                tmpA = tmpA -> next;
            }
        } else if (tmpB) {
            while(tmpB) {
                lenB ++;
                tmpB = tmpB -> next;
            }
        }
        tmpA = headA, tmpB = headB;
        if (lenA > lenB) {
            while(lenA > lenB) {
                tmpA = tmpA -> next;
                lenA --;
            }
        } else {
            while(lenA < lenB) {
                tmpB = tmpB -> next;
                lenB --;
            }
        }
        while(tmpA) {
            if (tmpA == tmpB) return tmpA;
            else {
                tmpA = tmpA -> next;
                tmpB = tmpB -> next;
            }
        }
        return NULL;
    }
};

92. 反转链表 II

92. 反转链表 II

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        if (left == right) return head;
        // 从头开始会报错,所以需要 new 一个新的 head
        ListNode* pre = new ListNode(0);
        pre -> next = head;
        ListNode* tmp = pre, *n;
        int idx = 0, cnt = right - left + 1;
        while(++ idx < left) tmp = tmp -> next;
        ListNode* reverP = tmp -> next;
        tmp -> next = NULL;
        
        while(cnt --) {
            n = reverP -> next;
            reverP -> next = tmp -> next;
            tmp -> next = reverP;
            reverP = n;
        }

        while(tmp -> next) tmp = tmp -> next;
        tmp -> next = reverP;

        return pre -> next;
    }
};

23. 合并K个排序链表

23. 合并K个排序链表

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if(!list1 || !list2) return list1 ? list1 : list2;
        ListNode* p1 = list1, *p2 = list2;
        ListNode* ret = new ListNode(0);
        ListNode* tmp = ret;
        while(list1 && list2) {
            if (list1 -> val < list2 -> val) {
                tmp -> next = list1;
                list1 = list1 -> next;
            } else {
                tmp -> next = list2;
                list2 = list2 -> next;
            }
            tmp = tmp -> next;
        }
        tmp -> next = list1 ? list1 : list2;
        
        return ret -> next;
    }

    ListNode* merge(vector<ListNode*>& lists, int left, int right) {
        if (left == right) return lists[left];
        else if(left > right) return NULL;
        int mid = left + right >> 1;
        return mergeTwoLists(merge(lists, left, mid), merge(lists, mid + 1, right));
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return merge(lists, 0, lists.size() - 1);
    }
};

415. 字符串相加

415. 字符串相加

class Solution {
public:
    string addStrings(string num1, string num2) {
        int l1 = num1.size() - 1, l2 = num2.size() - 1, add = 0;
        string ret = "";
        while(l1 >= 0 || l2 >= 0 || add != 0) {
            int a = l1 >= 0 ? num1[l1] - '0' : 0;
            int b = l2 >= 0 ? num2[l2] - '0' : 0;
            int sum = a + b + add;
            ret.push_back(sum % 10 + '0');
            add = sum / 10;
            l1 --;
            l2 --;
        }

        reverse(ret.begin(), ret.end());
        return ret;
    }
};

300. 最长上升子序列

300. 最长上升子序列

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size(), ret = 1;
        if (n < 2) return n;
        vector<int> f(n, 1);

        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < i; j ++) {
                if (nums[i] > nums[j]) f[i] = max(f[i], f[j] + 1);
            }
            ret = max(ret, f[i]);
        }

        return ret;
    }
};

142. 环形链表 II

142. 环形链表 II

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if (!head || !head -> next) return NULL;
        ListNode* slow = head, *fast = head;
        while(fast -> next && fast -> next -> next) {
            fast = fast -> next -> next;
            slow = slow -> next;
            if(fast == slow) {
                slow = head;
                while(slow != fast) {
                    slow = slow -> next;
                    fast = fast -> next;
                }
                return fast;
            }
        }
        return NULL;
    }
};

42. 接雨水

42. 接雨水

class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size(), ret = 0;
        vector<int> max_left(n);
        vector<int> max_right(n);

        max_left[0] = height[0];
        max_right[n - 1] = height[n - 1];
        for(int i = 1; i < n; i ++) max_left[i] = max(max_left[i - 1], height[i]);
        for(int i = n - 2; i >= 0; i --) max_right[i] = max(max_right[i + 1], height[i]);

        for (int i = 1; i < n - 1; i ++) {
            int tmp = min(max_left[i], max_right[i]) - height[i];
            if(tmp > 0) ret += tmp;
        }
        return ret;
    }
};

143. 重排链表

143. 重排链表

class Solution {
public:
    void reorderList(ListNode* head) {
        int n = 0, i = 0;
        unordered_map<int, ListNode*> umap;
        ListNode* tmp = head, *rec;
        while(tmp) {
            rec = tmp -> next;
            umap[n ++] = tmp;
            tmp -> next = NULL;
            tmp = rec;
        }
        if (n == 1) return ;

        tmp = head;
        tmp -> next = umap[n - 1 - i];
        i = 1;
        tmp = tmp -> next;
        while(i < n / 2) {
            tmp -> next = umap[i];
            tmp -> next -> next = umap[n - 1 - i];
            tmp = tmp -> next -> next;
            i ++;
        }
        if(n % 2 == 1) tmp -> next = umap[i];
    }
};

124. 二叉树中的最大路径和

124. 二叉树中的最大路径和

class Solution {
public:
    int ret = -1e7;

    int dfs(TreeNode* node) {
        if (node == NULL) return 0;
        int left = max(dfs(node -> left), 0);
        int right = max(dfs(node -> right), 0);
        
        int tmp = node -> val + left + right;
        ret = max(ret, tmp);

        return node -> val + max(left, right);
    }

    int maxPathSum(TreeNode* root) {
        dfs(root);
        return ret;
    }
};

19. 删除链表的倒数第 N 个结点

19. 删除链表的倒数第 N 个结点

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* fast = head, *slow = head;
        for(int i = 0; i < n; i ++) fast = fast -> next;
        if(!fast) return head -> next;

        while(fast -> next) {
            slow = slow -> next;
            fast = fast -> next;
        }
        slow -> next = slow -> next -> next;

        return head;
    }
};

94. 二叉树的中序遍历

94. 二叉树的中序遍历
递归做法

class Solution {
public:
    vector<int> ret;

    void inorder(TreeNode* root) {
        if(!root) return;
        if(root -> left) inorder(root -> left);
        ret.push_back(root -> val);
        if(root -> right) inorder(root -> right);
    }
    
    vector<int> inorderTraversal(TreeNode* root) {
        inorder(root);
        return ret;
    }
};

非递归做法

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> stk;
        vector<int> res;
        while(root || !stk.empty()) {
            while(root) {
                stk.push(root);
                root = root -> left;
            }
            res.push_back(stk.top() -> val);
            root = stk.top() -> right;
            stk.pop();
        }

        return res;
    }
};

232. 用栈实现队列

232. 用栈实现队列

class MyQueue {
private:
    stack<int> s1, s2;
    void reverseStack() {
        while(!s1.empty()) {
            s2.push(s1.top());
            s1.pop();
        }
    }

public:
    MyQueue() {}
    
    void push(int x) {
        s1.push(x);
    }
    
    int pop() {
        if(s2.empty()) reverseStack();
        
        int x = s2.top();
        s2.pop();    
        return x;
    }
    
    int peek() {
        if (s2.empty()) reverseStack();
        return s2.top();
    }
    
    bool empty() {
        return s1.empty() && s2.empty();
    }
};

72. 编辑距离

72. 编辑距离

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n = word1.size(), m = word2.size();
        if (n * m == 0) return n + m;
        vector<vector<int>> dp(n + 1, vector<int>(m + 1));

        for (int i = 0; i < n + 1; i ++) dp[i][0] = i;
        for (int j = 0; j < m + 1; j ++) dp[0][j] = j;

        for (int i = 1; i < n + 1; i ++) {
            for (int j = 1; j < m + 1; j ++) {
                int pre = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
                int left_down = word1[i - 1] == word2[j - 1] ? dp[i - 1][j - 1] : dp[i - 1][j - 1] + 1;
                dp[i][j] = min(pre, left_down);
            }
        }

        return dp[n][m];
    }
};

704. 二分查找

704. 二分查找

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        if(nums[left] == target) return left;
        else if(nums[right] == target) return right;
        int ret;
        while(left < right) {
            int mid = left + right >> 1;
            if (nums[mid] == target) return mid;
            else if(nums[mid] > target) right = mid;
            else left = mid + 1; 
        }

        return -1;
    }
};

56. 合并区间

56. 合并区间

bool cmp(vector<int>& a, vector<int>& b) {
    return a[0] < b[0];
}
class Solution {
public: 
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        int n = intervals.size(), i = 0, loc;
        if (n < 2) return intervals;
        sort(intervals.begin(), intervals.end(), cmp);

        vector<int> tmp;
        vector<vector<int>> ret;
        while(i < n) {
            tmp = intervals[i];
            loc = i + 1;
            while(loc < n && intervals[loc][0] <= tmp[1]) {
                tmp[1] = max(tmp[1], intervals[loc][1]);
                loc ++;
            }
            ret.push_back(tmp);
            i = loc;
        }

        return ret;
    }
};

4. 寻找两个正序数组的中位数

4. 寻找两个正序数组的中位数

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size() + nums2.size();
        int i = 0, j = 0, tag = 0;
        int tmp = n % 2 == 0?n/2-1:n/2;
        while(tag < tmp) {
            //均未走到末端
            if(i < nums1.size() && j < nums2.size()) {
                if(nums1[ i ] < nums2[ j ]) i++;
                else j++;                
            }
            //i走到最末端
            else if(i >= nums1.size()) j++;
            //j走到最末端
            else i++;
            tag++;
        }
        double ret = 0;
        if(n % 2 == 0) tag = 2;
        else tag = 1;
        while(tag--) { 
            if(i < nums1.size() && j < nums2.size()) {
                if(nums1[ i ] < nums2[ j ]) ret += nums1[ i++ ];
                else ret += nums2[ j++ ];                
            }
            else if(i >= nums1.size()) ret += nums2[ j++ ];
            else ret += nums1[ i++ ];
        }
        if(n % 2 == 0) return ret / 2.0;
        else return ret;
    }
};

1143. 最长公共子序列

1143. 最长公共子序列

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int n = text1.size(), m = text2.size();
        vector<vector<int>> dp(n + 1, vector<int>(m + 1));

        for (int i = 1; i < n + 1; i ++) {
            for (int j = 1; j < m + 1; j ++) {
                if (text1[i - 1] == text2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }

        return dp[n][m];
    }
};

199. 二叉树的右视图

199. 二叉树的右视图

class Solution {
public:
    vector<int> ret;
    
    void dfs(TreeNode* root, int level) {
        if (!root) return;
        
        if (ret.size() < level) {
            ret.push_back(root -> val);
        } else {
            ret[level - 1] = root -> val;
        } 
        if (root -> left) dfs(root -> left, level + 1);
        if (root -> right) dfs(root -> right, level + 1);
    }

    vector<int> rightSideView(TreeNode* root) {
        dfs(root, 1);
        return ret;
    }
};

82. 删除排序链表中的重复元素 II

82. 删除排序链表中的重复元素 II

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if (!head || !head -> next) return head;
        ListNode* pre = new ListNode(0);
        pre -> next = head;
        ListNode* tmp = pre;

        int num = -200;
        while(tmp -> next -> next) {
            if (tmp -> next -> val == tmp -> next -> next -> val) {
                num = tmp -> next -> val;
                tmp -> next = tmp -> next -> next;
            } else if (tmp -> next -> val == num) {
                tmp -> next = tmp -> next -> next;
            } else tmp = tmp -> next;
        }
        if (tmp -> next -> val == num) {
            tmp -> next = NULL;
        }

        return pre -> next;
    }
};

31. 下一个排列

31. 下一个排列

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        int n = nums.size(), left = n - 2;
        while(left >= 0 && nums[left] >= nums[left + 1]) {
            left --;
        }

        if (left < 0) {
            reverse(nums.begin(), nums.end());
        } else {
            int right = n - 1;
            while(nums[right] <= nums[left]) {
                right --;
            }
            swap(nums[left], nums[right]);
            reverse(nums.begin() + left + 1, nums.end());
        }

        return;
    }
};

93. 复原IP地址

93. 复原IP地址

class Solution {
public:
    vector<string> ret;

    void dfs(string& s, int start, int level) {
        if (level == 3) {
            if (isValid(s, start, s.size() - 1)) {
                ret.push_back(s);
            }
            return ;
        }

        for (int i = start; i < s.size(); i ++) {
            if (isValid(s, start, i)) {
                s.insert(s.begin() + i + 1, '.');
                dfs(s, i + 2, level + 1);
                s.erase(s.begin() + i + 1);
            }
            else {
                return;
            }
        }
    }

    bool isValid(string s, int start, int end) {
        if (s[start] == '0' || start > end) {
            return start == end;
        }
        int num = 0;
        for (int i = start; i <= end; i ++) {
            if (s[i] > '9' || s[i] < '0') {
                return false;
            }
            num = num * 10 + (s[i] - '0'); 
            if (num > 255) {
                return false;
            }
        }
        return true;
    }

    vector<string> restoreIpAddresses(string s) {
        ret.clear();
        if (s.size() < 4 || s.size() > 12) {
            return ret;
        }
        dfs(s, 0, 0);
        return ret;
    }
};

148. 排序链表

148. 排序链表

class Solution {
public:
    ListNode* merge(ListNode* ptr1, ListNode* ptr2) {
        if (ptr1 == NULL || ptr2 == NULL) {
            return ptr1 == NULL ? ptr2 : ptr1;
        }

        ListNode* ret;
        if (ptr1 -> val < ptr2 -> val) {
            ret = ptr1;
            ptr1 = ptr1 -> next;
            ret -> next = NULL;
        } else {
            ret = ptr2;
            ptr2 = ptr2 -> next;
            ret -> next = NULL;
        }

        ListNode* tmp = ret;
        while(ptr1 && ptr2) {
            if (ptr1 -> val < ptr2 -> val) {
                tmp -> next = ptr1;
                ptr1 = ptr1 -> next;
                tmp = tmp -> next;
                tmp -> next = NULL;
            } else {
                tmp -> next = ptr2;
                ptr2 = ptr2 -> next;
                tmp = tmp -> next;
                tmp -> next = NULL;
            }
        }

        if (ptr1) tmp -> next = ptr1;
        if (ptr2) tmp -> next = ptr2;

        return ret;
    }

    ListNode* lsort(ListNode* ptr) {
        // split to (ptr, slow)
        if (!ptr || !ptr -> next) {
            return ptr;
        }
        ListNode* slow = ptr, *fast = ptr;
        while(fast && fast -> next) {
            fast = fast -> next -> next;
            if (!fast || !fast -> next) {
                ListNode* tmp = slow -> next;
                slow -> next = NULL;
                slow = tmp;
                break;
            }
            slow = slow -> next;
        }

        // merge (ptr1, ptr2)
        return merge(lsort(ptr), lsort(slow));
    }

    ListNode* sortList(ListNode* head) {
        return lsort(head);
    }
};

70. 爬楼梯

70. 爬楼梯

class Solution {
public:
    int climbStairs(int n) {
        if (n <= 2) return n;
        vector<int> ret(n + 1);
        ret[1] = 1, ret[2] = 2;
        for (int i = 3; i <= n; i ++) {
            ret[i] = ret[i - 1] + ret[i - 2];
        }
        return ret[n];
    }
};

69. x 的平方根

69. x 的平方根

class Solution {
public:
    int mySqrt(int x) {
        int left = 0, right = x, mid;
        while(left < right) {
            mid = (long long)left + right + 1 >> 1;
            if (mid <= x / mid) left = mid;
            else right = mid - 1;
        }
        return left;
    }
};

2. 两数相加

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* head = NULL; ListNode* p = NULL;
        int a = 0;
        while(l1 != NULL && l2 != NULL) {
            int sum = l1->val + l2->val + a;
            if (p == NULL) {
                p = new ListNode(sum%10);
            } else {
                p -> next = new ListNode(sum%10);
                p = p -> next;
            }
            if (head == NULL) head = p;
            l1 = l1 -> next; l2 = l2 -> next;
            a = sum / 10;
        }
        while(l1 != NULL) {
            int sum = l1->val + a;
            p -> next = new ListNode(sum%10);
            p = p -> next;
            a = sum / 10;
            l1 = l1 -> next;
        }
        while(l2 != NULL) {
            int sum = l2->val + a;
            p -> next = new ListNode(sum%10);
            p = p -> next;
            a = sum / 10;
            l2 = l2 -> next;
        }

        if (a == 1) {
            p -> next = new ListNode(1);
        }
            
        return head;
    }
};

22. 括号生成

22. 括号生成

class Solution {
public:
    vector<string> ret;

    void dfs(string str, int l, int r, int n) {
        if(l > n || r > n || r > l) return;
        if(l == n && r == n) {ret.push_back(str); return;}
        dfs(str + '(', l + 1, r, n);
        dfs(str + ')', l, r + 1, n);
    }

    vector<string> generateParenthesis(int n) {
        ret.clear();
        dfs("", 0, 0, n);
        return ret;
    }
};

8. 字符串转换整数 (atoi)

class Solution {
public:
    int myAtoi(string s) {
        int sign = 1, tmp = 0, i = 0;

        while(s[i] == ' ')  ++i;              //1.忽略前导空格

        if(s[i] == '+' || s[i] == '-')        //2.确定正负号
            sign = (s[i++] == '-') ? -1 : 1;  //s[i]为+的话sign依旧为1,为-的话sign为-1

        while(s[i] >= '0' && s[i] <= '9')     //3.检查输入是否合法
        {
            if(tmp > INT_MAX / 10 || (tmp == INT_MAX / 10 && s[i] - '0' > 7))    //4.是否溢出
                return sign == 1 ? INT_MAX : INT_MIN;
            tmp = tmp * 10 + (s[i++] - '0');  //5.不加括号有溢出风险
        }
        return tmp * sign;
    }
};

239. 滑动窗口最大值

239. 滑动窗口最大值

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> ans;
        deque<int> idx;

        for (int i = 0; i < n; i ++) {
            if (!idx.empty() && i - k + 1 > idx.front()) {
                idx.pop_front();
            }
            while (!idx.empty() && nums[idx.back()] < nums[i]) {
                idx.pop_back();
            } 
            idx.push_back(i);
            if (i >= k - 1) {
                ans.push_back(nums[idx.front()]);
            }
        }

        return ans;
    }
};

41. 缺失的第一个正数

41. 缺失的第一个正数

class Solution {
public:
    int firstMissingPositive(vector<int> &nums) {
        int n = nums.size();
        for (int i = 0; i < n; i ++) {
            while (nums[i] !=  i + 1) {
                if (nums[i] < 1 || nums[i] > n || nums[i] == nums[nums[i] - 1]) {
                    break;
                }
                int idx = nums[i] - 1;
                nums[i] = nums[idx];
                nums[idx] = idx + 1;
            }
        }
        for (int i = 0; i < n; i ++) {
            if (nums[i] != i + 1) return i + 1;
        }
        return n + 1;
    }
};

剑指 Offer 22. 链表中倒数第k个节点

剑指 Offer 22. 链表中倒数第k个节点

class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        ListNode* slow, * fast;
        slow = head, fast = head;
        for (int i = 0; i < k; i ++) {
            fast = fast -> next;
        }
        if (!fast) return slow;

        while(fast) {
            slow = slow -> next;
            fast = fast -> next;
        }

        return slow;
    }
};

165. 比较版本号

165. 比较版本号

class Solution {
public:
    int compareVersion(string version1, string version2) {
        char cr;
        int num1, num2;
        istringstream istr1(version1);
        istringstream istr2(version2);

        while(bool(istr1 >> num1) + bool(istr2 >> num2)) {
            if (num1 > num2) return 1;
            else if (num1 < num2) return -1;
            
            num1 = 0;
            num2 = 0;
            istr1 >> cr;
            istr2 >> cr;
        }

        return 0;
    }
};

76. 最小覆盖子串

78. 子集

78. 子集

class Solution {
public:
    vector<vector<int>> ret;
    vector<int> tmp;

    void dfs(vector<int>& nums, int loc) {
        if (loc > nums.size()) return;
        else if (loc == nums.size()) {
            ret.push_back(tmp);
            return;
        }

        dfs(nums, loc + 1);
        tmp.push_back(nums[loc]);
        dfs(nums, loc + 1);
        tmp.erase(tmp.end() - 1);
    }

    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(nums, 0);
        return ret;
    }
};

322. 零钱兑换

322. 零钱兑换

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        if (amount <= 0) return amount == 0 ? 0 : -1;
        vector<int> dp(amount + 1);
        for (int i = 0; i < amount + 1; i ++) {
            dp[i] = 1e7;
        } dp[0] = 0;

        for (int i = 0; i < coins.size(); i ++) {
            for (int j = coins[i]; j <= amount; j ++) {
                dp[j] = min(dp[j], dp[j - coins[i]] + 1);
            }
        }

        return dp[amount] < 1e7 ? dp[amount] : -1;
    }
};

32. 最长有效括号

添加链接描述

class Solution {
public:
    int longestValidParentheses(string s) {
        int ans = 0;
        stack<int> stk;
        stk.push(-1);
        for (int i = 0; i < s.length(); i ++) {
            if (s[i] == '(') {
                stk.push(i);
            } else {
                stk.pop();
                if (!stk.empty()) {
                    ans = max(i - stk.top(), ans);
                } else {
                    stk.push(i);
                }
            }
        }

        return ans;
    }
};

105. 从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树

class Solution {
public:
    TreeNode* createTree(vector<int>& preorder, int x1, int y1, vector<int>& inorder, int x2, int y2) {
        if (x1 > y1) return NULL;
        else if (x1 == y1) return new TreeNode(preorder[x1]);

        TreeNode* ret = new TreeNode(preorder[x1]);
        int loc = x2;
        while (inorder[loc] != preorder[x1]) {
            loc ++;
        }

        if (loc == x2) {
            ret -> left = NULL;
        } else {
            ret -> left = createTree(preorder, x1 + 1, x1 + loc - x2, inorder, x2, loc - 1);
        }
        if (loc == y2) {
            ret -> right = NULL;
        } else {
            ret -> right = createTree(preorder, x1 + 1 + loc - x2, y1, inorder, loc + 1, y2);
        }

        return ret;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if (preorder[0] == -1) return new TreeNode(-1);

        return createTree(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
    }
};

155. 最小栈

155. 最小栈

class MinStack {
private:
    stack<pair<int, int>> stk;

public:
    MinStack() {

    }
    
    void push(int val) {
        if (stk.empty()) {
            stk.push({val, val});
        } else {
            stk.push({val, min(val, stk.top().second)});
        }
    }
    
    void pop() {
        stk.pop();
    }
    
    int top() {
        return stk.top().first;
    }
    
    int getMin() {
        return stk.top().second;
    }
};

43. 字符串相乘

43. 字符串相乘

class Solution {
public:
    string multiply(string num1, string num2) {
        if (num1 == "0" || num2 == "0") return "0";
        if (num1 == "1" || num2 == "1") return num1 == "1" ? num2 : num1;
        string ans = "";
        if (num1.size() < num2.size()) {
            string tmp;
            tmp = num1;
            num1 = num2;
            num2 = tmp;
        } 
        reverse(num1.begin(), num1.end()), reverse(num2.begin(), num2.end());

        int add = 0, n = num1.size(), m = num2.size();
        for (int i = 0; i < n + m - 1; i ++) {
            for (int j = 0; j < m; j ++) {
                if (i >= j && i < j + n) {
                    add += (num2[j] - '0') * (num1[i - j] - '0');
                }
            }
            ans.insert(ans.begin(), add % 10 + '0');
            add /= 10;
        }

        while (add != 0) {
            ans.insert(ans.begin(), add % 10 + '0');
            add /= 10;
        }

        return ans;
    }
};               

151. 翻转字符串里的单词

151. 反转字符串中的单词

class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip()
        words = s.split(' ')[::-1]
        ans = ""
        for w in words:
            if len(w.strip()) == 0:
                continue
            ans += w.strip()
            ans += ' '
        
        return ans[:-1]

32. 最长有效括号

32. 最长有效括号

class Solution {
public:
    int longestValidParentheses(string s) {
        int ans = 0;
        stack<int> stk;
        stk.push(-1);
        for (int i = 0; i < s.length(); i ++) {
            if (s[i] == '(') {
                stk.push(i);
            } else {
                stk.pop();
                if (!stk.empty()) {
                    ans = max(i - stk.top(), ans);
                } else {
                    stk.push(i);
                }
            }
        }

        return ans;
    }
};

144. 二叉树的前序遍历

144. 二叉树的前序遍历

class Solution {
public:
    vector<int> ans;

    void preTravel(TreeNode* root) {
        if (root == NULL) return ;
        ans.push_back(root -> val);
        if (root -> left != NULL) preTravel(root -> left);
        if (root -> right != NULL) preTravel(root -> right);
    }

    vector<int> preorderTraversal(TreeNode* root) {
        preTravel(root);

        return ans;
    }
};

110. 平衡二叉树

110. 平衡二叉树

class Solution {
public:
    int recur(TreeNode* root) {
        if (root == nullptr) return 0;
        int left = recur(root->left);
        if (left == -1) return -1;
        int right = recur(root->right);
        if (right == -1) return -1;
        return abs(left - right) < 2 ? max(left, right) + 1 : -1;
    }

    bool isBalanced(TreeNode* root) {
        return recur(root) != -1;
    }
};

101. 对称二叉树

101. 对称二叉树

class Solution {
public:
    vector<vector<int>> travel;

    void layerTravel(TreeNode* root, int maxDepth, int level) {
        if (travel.size() < level) {
            if (root == NULL) travel.push_back({-200});
            else travel.push_back({root -> val});
        } else {
            if (root == NULL) travel[level - 1].push_back({-200});
            else travel[level - 1].push_back(root -> val);
        }
        if (level <= maxDepth) {
            if (root == NULL) layerTravel(NULL, maxDepth, level + 1);
            else if (root -> left == NULL) layerTravel(NULL, maxDepth, level + 1);
            else layerTravel(root -> left, maxDepth, level + 1);
        }
        if (level <= maxDepth) {
            if (root == NULL) layerTravel(NULL, maxDepth, level + 1);
            else if (root -> right == NULL) layerTravel(NULL, maxDepth, level + 1);
            else layerTravel(root -> right, maxDepth, level + 1);
        }
    }

    int getDepth(TreeNode* root) {
        if (root == NULL) return 0;
        else if (root -> left == NULL && root -> right == NULL) return 1;
        return max(getDepth(root -> left), getDepth(root -> right)) + 1;
    }

    bool isSymmetric(TreeNode* root) {
        int depth = getDepth(root);
        layerTravel(root, depth, 1);
        for (int i = 0; i < travel.size(); i ++) {
            if (travel[i].size() % 2 == 1 && i != 0) return false;
            for (int j = 0; j < travel[i].size() / 2; j ++) {
                if (travel[i][j] != travel[i][travel[i].size() - 1 - j]) return false;
            }
        }
        return true;
    }
};

104. 二叉树的最大深度

104. 二叉树的最大深度

class Solution {
public:
    int dfs(TreeNode* root) {
        if (root == NULL) return 0;
        else if (root -> left == NULL && root -> right == NULL) return 1;
        else if (root -> left == NULL) return dfs(root -> right) + 1;
        else if (root -> right == NULL) return dfs(root -> left) + 1;
        else return max(dfs(root -> left), dfs(root -> right)) + 1;
    }

    int maxDepth(TreeNode* root) {
        return dfs(root);
    }
};

129. 求根到叶子节点数字之和

129. 求根到叶子节点数字之和

class Solution {
public:
    int ans = 0;

    void travel(TreeNode* root, int pre) {
        if (root == NULL) return ;
        if (root -> left == NULL && root -> right == NULL) {
            ans += pre * 10 + root -> val;
        } else if (root -> left == NULL) {
            travel(root -> right, pre * 10 + root -> val);
        } else if (root -> right == NULL) {
            travel(root -> left, pre * 10 + root -> val);
        } else {
            travel(root -> left, pre * 10 + root -> val);
            travel(root -> right, pre * 10 + root -> val);
        }
    }

    int sumNumbers(TreeNode* root) {
        travel(root, 0);
        return ans;
    }
};

543. 二叉树的直径

543. 二叉树的直径

class Solution {
public:
    int ans = 0;

    int dfs(TreeNode* root) {
        if (root == NULL) return -1;
        else if (root -> left == NULL && root -> right == NULL) return 0;

        int left, right;
        left = dfs(root -> left);
        right = dfs(root -> right);
        ans = max(ans, left + right + 2);
        
        return max(left, right) + 1;
    }

    int diameterOfBinaryTree(TreeNode* root) {
        int tmp;
        tmp = dfs(root);
        ans = max(tmp, ans);

        return ans;
    }
};

98. 验证二叉搜索树

98. 验证二叉搜索树

class Solution {
public:
    vector<int> t;

    void midTravel(TreeNode* root) {
        if (root == NULL) return ;
        else if (root -> left == NULL && root -> right == NULL) {
            t.push_back(root -> val);
            return ;
        }

        if (root -> left != NULL) midTravel(root -> left);
        t.push_back(root -> val);
        if (root -> right != NULL) midTravel(root -> right);
    }

    bool isValidBST(TreeNode* root) {
        midTravel(root);

        for (int i = 1; i < t.size(); i ++) {
            if (t[i] <= t[i - 1]) {
                return false;
            }
        }
        return true;
    }
};

113. 路径总和 II

470. 用 Rand7() 实现 Rand100()

64. 最小路径和

39. 组合总和

48. 旋转图像

394. 字符串解码

234. 回文链表

112. 路径总和

34. 在排序数组中查找元素的最后一个位置

221. 最大正方形

240. 搜索二维矩阵 II

240. 搜索二维矩阵 II

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int i = 0, j = matrix[0].size() - 1;
        while(i >= 0 && i < matrix.size() && j >= 0 & j < matrix[0].size()) {
            if (matrix[i][j] == target) return true;
            else if (matrix[i][j] < target) i++;
            else j --;
        }
        
        return false;
    }
};

169. 多数元素

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值