• 剑指offer题解(第二版)


    实现哈希表,好多人碰到了这个,加在这里

    705. 设计哈希集合 - 力扣(LeetCode) (leetcode-cn.com)

     1 class MyHashSet {
     2 private:
     3     static const int base = 769;
     4     vector<list<int>> data;
     5     static int hash(int key) {
     6         return key % base;
     7     }
     8 public:
     9     /** Initialize your data structure here. */
    10     MyHashSet(): data(base) {}
    11     
    12     void add(int key) {
    13         int h = hash(key);
    14         for (auto it = data[h].begin(); it != data[h].end(); it++) {
    15             if ((*it) == key) {
    16                 return;
    17             }
    18         }
    19         data[h].push_back(key);
    20     }
    21     
    22     void remove(int key) {
    23         int h = hash(key);
    24         for (auto it = data[h].begin(); it != data[h].end(); it++) {
    25             if ((*it) == key) {
    26                 data[h].erase(it);
    27                 return;//不加报错
    28             }
    29         }
    30     }
    31     bool contains(int key) {
    32         int h = hash(key);
    33         for (auto it = data[h].begin(); it != data[h].end(); it++) {
    34             if ((*it) == key) {
    35                 return true;
    36             }
    37         }
    38         return false;
    39     }
    40 };
    View Code

    剑指 Offer 03. 数组中重复的数字 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int findRepeatNumber(vector<int>& nums) {
     4         int a[100000] = {0};
     5         for(int i=0;i<nums.size();i++){
     6             if(a[nums[i]] == 1)
     7                 return nums[i];
     8             a[nums[i]] = 1;
     9         }
    10         return 0;
    11     }
    12 };
    View Code

     剑指 Offer 04. 二维数组中的查找 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     bool ans = false;
     4     void f(vector<vector<int>>& matrix,vector<vector<int>>& vis,int target,int x,int y){
     5         if(x>=matrix.size()||y>=matrix[0].size())
     6             return ;
     7         if(vis[x][y])
     8             return ;
     9         vis[x][y] = 1;
    10         if(target == matrix[x][y]){
    11             ans = true;
    12             return ;
    13         }
    14         if(x+1 < matrix.size()&&target >= matrix[x+1][y]&&vis[x+1][y] == 0)
    15             f(matrix,vis,target,x+1,y);
    16         if(y+1 < matrix[0].size()&&target >= matrix[x][y+1]&& vis[x][y+1] == 0)
    17             f(matrix,vis,target,x,y+1);
    18     }
    19     bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
    20         if(matrix.size() == 0)
    21             return ans;
    22         vector<vector<int>> vis(matrix.size(),vector<int>(matrix[0].size(),0));
    23         f(matrix,vis,target,0,0);
    24         return ans;
    25     }
    26 };
    View Code

     剑指 Offer 05. 替换空格 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     string replaceSpace(string s) {
     4         string ans = "";
     5         for(int i=0;i<s.size();i++){
     6             if(s[i]!=' ')
     7                 ans+=s[i];
     8             else
     9                 ans+="%20";
    10         }
    11         return ans;
    12     }
    13 };
    View Code

     剑指 Offer 06. 从尾到头打印链表 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<int> reversePrint(ListNode* head) {
     4         ListNode* pre = nullptr,*cur = head;
     5         while(cur){
     6             ListNode *t = cur->next;
     7             cur->next = pre;
     8             pre = cur;
     9             cur = t;
    10         }
    11         vector<int> ans;
    12         while(pre){
    13             ans.push_back(pre->val);
    14             pre = pre->next;
    15         }
    16         return ans;
    17     }
    18 };
    View Code

    剑指 Offer 07. 重建二叉树 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     TreeNode* f(vector<int>& preorder, vector<int>& inorder,int leftp,int rightp,int lefti,int righti){
     4         if(leftp>rightp||lefti>righti)
     5             return nullptr;
     6         TreeNode* root = new TreeNode(preorder[leftp]);
     7         int mid;
     8         for(int i=lefti;i<=righti;i++){
     9             if(inorder[i] == preorder[leftp]){
    10                 mid = i;
    11                 break;
    12             }
    13         }
    14         int leftlen = mid-lefti+1;
    15         root->left = f(preorder,inorder,leftp+1,leftp+leftlen-1,lefti,mid-1);
    16         root->right = f(preorder,inorder,leftp+leftlen,rightp,mid+1,righti);
    17         return root;
    18     }
    19     TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    20         return f(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);
    21 
    22     }
    23 };
    View Code

     剑指 Offer 09. 用两个栈实现队列 - 力扣(LeetCode) (leetcode-cn.com)

     1 class CQueue {
     2 public:
     3     CQueue() {
     4 
     5     }
     6     stack<int> s1,s2;
     7     void appendTail(int value) {
     8         s1.push(value);
     9     }
    10     
    11     int deleteHead() {
    12         if(s2.empty()){
    13             while(!s1.empty()){
    14                 s2.push(s1.top());
    15                 s1.pop();
    16             }
    17             
    18         }
    19         if(s2.empty())
    20             return -1;
    21         int head = s2.top();
    22         s2.pop();
    23         return head;
    24     }
    25 };
    View Code

     剑指 Offer 10- I. 斐波那契数列 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int fib(int n) {
     4         long a = 0,b = 1;
     5         if(n==0)
     6             return a;
     7         while(n>=2){
     8             long c = a+b%1000000007;
     9             a = b;
    10             b = c;
    11             n--;
    12         }
    13         return b%1000000007;
    14     }
    15 };
    View Code

     剑指 Offer 10- II. 青蛙跳台阶问题 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int numWays(int n) {
     4         long a = 1,b = 2;
     5         if(n==0||n==1)
     6             return a;
     7         while(n>2){
     8             long c = a+b%1000000007;
     9             a = b;
    10             b = c;
    11             n--;
    12         }
    13         return b%1000000007;
    14     }
    15 };
    View Code

    剑指 Offer 11. 旋转数组的最小数字 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int minArray(vector<int>& numbers) {
     4         int l = 0,r = numbers.size()-1;
     5         while(l<r){
     6             int mid  =(l+r)/2;
     7             if(numbers[mid]>numbers[r]){
     8                 l = mid+1;
     9             }else if(numbers[mid]<numbers[r]){
    10                 r = mid;//细节边界
    11             }else{
    12                 r--;
    13             }
    14         }
    15         return numbers[l];
    16     }
    17 };
    View Code

     剑指 Offer 12. 矩阵中的路径 - 力扣(LeetCode) (leetcode-cn.com)

    这道题真离谱,多一点点代码都过不了

     1 class Solution {
     2 public:
     3     bool exist(vector<vector<char>>& board, string word) {
     4         rows = board.size();
     5         cols = board[0].size();
     6         for(int i = 0; i < rows; i++) {
     7             for(int j = 0; j < cols; j++) {
     8                 if(dfs(board, word, i, j, 0)) return true;
     9             }
    10         }
    11         return false;
    12     }
    13 private:
    14     int rows, cols;
    15     bool dfs(vector<vector<char>>& board, string word, int i, int j, int k) {
    16         if(i >= rows || i < 0 || j >= cols || j < 0 || board[i][j] != word[k]) return false;
    17         if(k == word.size() - 1) return true;
    18         board[i][j] = '\0';
    19         bool res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) || 
    20                       dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i , j - 1, k + 1);
    21         board[i][j] = word[k];
    22         return res;
    23     }
    24 };
    View Code

     剑指 Offer 13. 机器人的运动范围 - 力扣(LeetCode) (leetcode-cn.com)

    这种题四个方向爆搜,换汤不换药

     1 class Solution {
     2 public:
     3     int ans;
     4     int vis[200][200];
     5     void f(int m, int n, int k,int x,int y){
     6         if(x<0||x>=m||y<0||y>=n)
     7             return ;
     8         int t = 0;
     9         int x1 = x,y1 = y;//后面还要用x,y,不能直接修改xy
    10         while(x1||y1){
    11             t = t + x1%10 + y1%10;
    12             x1/=10,y1/=10;
    13         }
    14         if(t>k||vis[x][y])
    15             return ;
    16         ans++;
    17         vis[x][y] = 1;
    18         f(m,n,k,x+1,y);
    19         f(m,n,k,x,y+1);
    20         f(m,n,k,x-1,y);
    21         f(m,n,k,x,y-1);
    22     }
    23     int movingCount(int m, int n, int k) {
    24         f(m,n,k,0,0);
    25         return ans;
    26     }
    27 };
    View Code

     剑指 Offer 14- I. 剪绳子 - 力扣(LeetCode) (leetcode-cn.com)

    数学问题,多举例,先解决边界问题等特殊情况再找一般规律

     1 class Solution {
     2 public:
     3     int cuttingRope(int n) {
     4         if(n<=3){
     5             return n-1;
     6         }
     7         int ans = 1;
     8         while(n){
     9             if(n==4){
    10                 ans*=4;
    11                 break;
    12             }
    13             if(n==2){
    14                 ans*=2;
    15                 break;
    16             }
    17             ans*=3;
    18             n-=3;
    19 
    20                 
    21         }
    22         return ans;
    23     }
    24 };
    View Code

     剑指 Offer 14- II. 剪绳子 II - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int cuttingRope(int n) {
     4         if(n<=3)
     5             return n-1;
     6         int ans = 1;
     7         while(n){
     8             if(n==4){
     9                 ans = (((ans+ans)%1000000007+ans)%1000000007+ans)%1000000007;
    10                 break;
    11             }
    12             if(n==2){
    13                 ans = (ans+ans)%1000000007;
    14                 break;
    15             }
    16             ans=((ans+ans)%1000000007+ans)%1000000007;
    17             n-=3;
    18         }
    19         return ans;
    20     }
    21 };
    View Code

     剑指 Offer 15. 二进制中1的个数 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int hammingWeight(uint32_t n) {
     4         int ans = 0;
     5         while(n){
     6             ans = ans+n%2;
     7             n = n>>1;
     8         }
     9         return ans;
    10     }
    11 };
    View Code

     剑指 Offer 16. 数值的整数次方 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {//1.00000   2147483647 O(n)过不了必定二分!
     2 public:
     3     double myPow(double x, int n) {//二分,答案是两部分乘积
     4         if(n==0)
     5             return 1;
     6         if(n==1)
     7             return x;
     8         if(n==-1)
     9             return 1/x;
    10         double half = myPow(x,n/2);
    11         double mod = myPow(x,n%2);
    12         return half*half*mod;
    13     }
    14 };
    View Code

     剑指 Offer 17. 打印从1到最大的n位数 - 力扣(LeetCode) (leetcode-cn.com)

    这道题原题大数,返回类型vector<string>。回溯求解,外面一个for循环表示1-n各个位数的答案,回溯里注意长度0&&i==0这种情况continue就行

     1 class Solution {
     2 public:
     3     vector<int> printNumbers(int n) {
     4         if(n==0)
     5             return {};
     6         int m = 1;
     7         while(n){
     8             m*=10;
     9             n--;
    10         }
    11         vector<int> ans;
    12         for(int i=1;i<m;i++){
    13             ans.push_back(i);
    14         }
    15         return ans;
    16     }
    17 };
    View Code

     剑指 Offer 18. 删除链表的节点 - 力扣(LeetCode) (leetcode-cn.com)

    评论说原著给的参数是链表节点不是节点值,给节点可以直接O(1)方法是把下个节点的值赋给当前节点,然后删除下个节点。如果删除节点是末尾节点,那么从头遍历找到前驱节点进行删除。平均复杂度O(1)。末尾节点不能直接赋值nullptr,改变不了原链表。

     1 class Solution {
     2 public:
     3     ListNode* deleteNode(ListNode* head, int val) {
     4         if(!head)
     5             return head;
     6         if(head->val == val)
     7             return head->next;
     8         ListNode* pre = head;
     9         ListNode* cur = head->next;
    10         while(cur){
    11             if(cur->val == val){
    12                 pre->next = cur->next;
    13             }
    14             pre = cur;
    15             cur = cur->next;
    16         }
    17         return head;
    18     }
    19 };
    View Code
     1 class Solution {
     2 public:
     3     ListNode* deleteNode(ListNode* head, int val) {
     4         if(!head)
     5             return head;
     6         if(head->val == val)
     7             return head->next;
     8         head->next = deleteNode(head->next,val);
     9         return head;
    10     }
    11 };
    View Code 递归

     剑指 Offer 20. 表示数值的字符串 - 力扣(LeetCode) (leetcode-cn.com)

    这题,有限状态机。最近搞webserver项目,里面解析http请求也讲到了有限状态机,还有点懵。

     剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<int> exchange(vector<int>& nums) {
     4         int j = 0;
     5         for(int i=0;i<nums.size();i++){
     6             if(nums[i]%2==1){
     7                 swap(nums[j],nums[i]);
     8                 j++;
     9             }
    10         }
    11         return nums;
    12     }
    13 };
    View Code

     剑指 Offer 24. 反转链表 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     ListNode* reverseList(ListNode* head) {
     4         ListNode* pre = nullptr,*cur = head;
     5         while(cur){
     6             ListNode *t = cur->next;
     7             cur->next = pre;
     8             pre = cur;
     9             cur = t;
    10         }
    11         return pre;//当前cur位空,返回pre
    12     }
    13 };
    View Code

     剑指 Offer 25. 合并两个排序的链表 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
     4         ListNode* head = new ListNode();
     5         ListNode* cur = head;
     6         while(l1||l2){
     7             int x = l1==nullptr?INT_MAX:l1->val;
     8             int y = l2==nullptr?INT_MAX:l2->val;
     9             if(x<y){
    10                 cur->next = l1;
    11                 l1 = l1->next;
    12             }else{
    13                 cur->next = l2;
    14                 l2 = l2->next;
    15             }
    16             cur = cur->next;
    17         }
    18         return head->next;
    19     }
    20 };
    View Code

     剑指 Offer 26. 树的子结构 - 力扣(LeetCode) (leetcode-cn.com)

    遇事不决暴力解决,越写越明朗

     1 class Solution {
     2 public:
     3     bool f(TreeNode* A,TreeNode* B){
     4         if(B == nullptr)
     5             return true;
     6         if(A == nullptr)
     7             return false;
     8         if(A->val!=B->val)
     9             return false;
    10         return f(A->left,B->left)&&f(A->right,B->right);
    11     }
    12     bool isSubStructure(TreeNode* A, TreeNode* B) {//B空树返回false
    13         if(B == nullptr)
    14             return false;
    15         if(A == nullptr)
    16             return false;
    17         if(A->val == B->val){
    18             return f(A,B)||isSubStructure(A->left,B)||isSubStructure(A->right,B);
    19         }
    20         return isSubStructure(A->left,B)||isSubStructure(A->right,B);
    21     }
    22 };
    View Code

     剑指 Offer 27. 二叉树的镜像 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {//注意如果不用临时变量,会有覆盖问题导致节点丢失
     2 public:
     3     TreeNode* mirrorTree(TreeNode* root) {
     4         if(!root)
     5             return root;
     6         TreeNode *t = root->left;
     7         root->left = mirrorTree(root->right);
     8         root->right = mirrorTree(t);
     9         return root;
    10     }
    11 };
    View Code

     剑指 Offer 28. 对称的二叉树 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     bool f(TreeNode* root1,TreeNode* root2){
     4         if(root1==nullptr&&root2==nullptr)
     5             return true;
     6         if(root1==nullptr||root2==nullptr)
     7             return false;
     8         if(root1->val!=root2->val)
     9             return false;
    10         return f(root1->left,root2->right)&&f(root1->right,root2->left);
    11     }
    12     bool isSymmetric(TreeNode* root) {
    13         return f(root,root);
    14     }
    15 };
    View Code

    剑指 Offer 29. 顺时针打印矩阵 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<int>ans;
     4     int m,n;
     5     void f(vector<vector<int>>& matrix,int x,int y){
     6         if(x>=m||y>=n)
     7             return;
     8         for(int j=y;j<n;j++){
     9             ans.push_back(matrix[x][j]);
    10         }
    11         x++;
    12         if(x>=m||y>=n)
    13             return;
    14         for(int i=x;i<m;i++){
    15             ans.push_back(matrix[i][n-1]);
    16         }
    17         n--;
    18         if(x>=m||y>=n)
    19             return;
    20         for(int j=n-1;j>=y;j--){
    21             ans.push_back(matrix[m-1][j]);
    22         }
    23         m--;
    24         if(x>=m||y>=n)
    25             return;
    26         for(int i=m-1;i>=x;i--){
    27             ans.push_back(matrix[i][y]);
    28         }
    29         y++;
    30         f(matrix,x,y);
    31     }
    32     vector<int> spiralOrder(vector<vector<int>>& matrix) {
    33         if(matrix.size()==0)
    34             return ans;
    35         m = matrix.size();
    36         n = matrix[0].size();
    37         f(matrix,0,0);
    38         return ans;
    39     }
    40 };
    View Code

     剑指 Offer 30. 包含min函数的栈 - 力扣(LeetCode) (leetcode-cn.com)

    空间换时间,链表维护栈,链表里元素多一个min,记录在此之前的最小值

     1 class Node{
     2     public:
     3         int data;
     4         int min;
     5         Node* next;
     6         Node(int data,int min,Node* next){
     7             this->data = data;
     8             this->min = min;
     9             this->next = next;
    10         }
    11     };
    12 class MinStack {
    13 public:
    14     Node* head;
    15     MinStack() {
    16         head = new Node(0,0,nullptr);
    17     }
    18     
    19     void push(int x) {
    20         int y = head->next?head->next->min:x;//维护最小值
    21         y = y<x?y:x;
    22         Node *t = new Node(x,y,head->next);
    23         head->next = t;
    24     }
    25     
    26     void pop() {
    27         head->next = head->next->next;
    28     }
    29     
    30     int top() {
    31         return head->next->data;
    32     }
    33     
    34     int min() {
    35         return head->next->min;
    36     }
    37     
    38 };
    View Code

     剑指 Offer 31. 栈的压入、弹出序列 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
     4         stack<int>st;
     5         int j=0;
     6         for(int i=0;i<pushed.size();i++){
     7             st.push(pushed[i]);
     8             while(!st.empty()&&st.top() == popped[j]){
     9                 j++;
    10                 st.pop();
    11             }
    12         }
    13         if(j==pushed.size()&&st.empty())
    14             return true;
    15         else
    16             return false;
    17     }
    18 };
    View Code

     剑指 Offer 32 - II. 从上到下打印二叉树 II - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<vector<int>> levelOrder(TreeNode* root) {
     4         vector<vector<int>> result;
     5         if(root==nullptr)
     6             return result;
     7         queue<TreeNode*>que;
     8         que.push(root);
     9         while(!que.empty()){
    10             int n = que.size();
    11             vector<int>path;
    12             for(int i=0;i<n;i++){
    13                 TreeNode* t = que.front();
    14                 que.pop();
    15                 if(t){
    16                     path.push_back(t->val);
    17                     if(t->left)
    18                         que.push(t->left);
    19                     if(t->right)
    20                         que.push(t->right);
    21                 }
    22                 
    23             }
    24             result.push_back(path);
    25         }
    26         return result;
    27     }
    28 };
    View Code

     剑指 Offer 32 - III. 从上到下打印二叉树 III - 力扣(LeetCode) (leetcode-cn.com)

     1 /**
     2  * Definition for a binary tree node.
     3  * struct TreeNode {
     4  *     int val;
     5  *     TreeNode *left;
     6  *     TreeNode *right;
     7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     8  * };
     9  */
    10 class Solution {
    11 public:
    12     vector<vector<int>> levelOrder(TreeNode* root) {
    13         if(root == nullptr)
    14             return {};
    15         vector<vector<int>> result;
    16         queue<TreeNode*>que;
    17         que.push(root);
    18         int k = 1;
    19         while(!que.empty()){
    20             vector<int>path;
    21             int n = que.size();
    22             while(n--){
    23                 TreeNode* t = que.front();
    24                 que.pop();
    25                 path.push_back(t->val);
    26                 if(t->left)
    27                     que.push(t->left);
    28                 if(t->right)
    29                     que.push(t->right);
    30             }
    31             if(k%2==0){
    32                 reverse(path.begin(),path.end());
    33             }
    34             result.push_back(path);
    35             k++;
    36         }
    37         return result;
    38     }
    39 };
    View Code

     剑指 Offer 33. 二叉搜索树的后序遍历序列 - 力扣(LeetCode) (leetcode-cn.com)

    这道题时间复杂度没看懂

     1 class Solution {
     2 public:
     3     bool f(vector<int>& postorder,int l,int r){
     4         if(l>=r)
     5             return true;
     6         int i = l;
     7         while(postorder[i]<postorder[r]){
     8             i++;
     9         }
    10         int mid = i;
    11         while(postorder[i]>postorder[r]){
    12             i++;
    13         }
    14         return i==r&&f(postorder,l,mid-1)&&f(postorder,mid,r-1);
    15     }
    16     bool verifyPostorder(vector<int>& postorder) {
    17         return f(postorder,0,postorder.size()-1);
    18     }
    19 };
    View Code

     剑指 Offer 34. 二叉树中和为某一值的路径 - 力扣(LeetCode) (leetcode-cn.com)

     1 /**
     2  * Definition for a binary tree node.
     3  * struct TreeNode {
     4  *     int val;
     5  *     TreeNode *left;
     6  *     TreeNode *right;
     7  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     8  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     9  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
    10  * };
    11  */
    12 class Solution {
    13 public:
    14     vector<int>path;
    15     vector<vector<int>> result;
    16     void f(TreeNode* root,int target,int num){
    17         if(!root)
    18             return ;
    19         num+=root->val;
    20         path.push_back(root->val);
    21         if(root->left==nullptr&&root->right==nullptr){
    22             if(num==target){
    23                 result.push_back(path);
    24             }
    25         }
    26         f(root->left,target,num);
    27         f(root->right,target,num);
    28         path.pop_back();
    29     }
    30     vector<vector<int>> pathSum(TreeNode* root, int target) {
    31         f(root,target,0);
    32         return result;
    33     }
    34 };
    View Code

     剑指 Offer 35. 复杂链表的复制 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     Node* copyRandomList(Node* head) {
     4         if(head == nullptr)
     5             return nullptr;
     6         Node* cur = head;
     7         while(cur){
     8             Node* t = new Node(cur->val);
     9             t->next = cur->next;
    10             cur->next = t;
    11             cur = cur->next->next;
    12         }
    13         cur = head;
    14         while(cur){
    15                 cur->next->random = cur->random?cur->random->next:nullptr;//为啥是random->next,因为random要只向新生成的节点
    16                 cur = cur->next->next;
    17         }
    18         cur = head;
    19         Node *ans = head->next;
    20         Node *copy = head->next;
    21         while(cur){
    22             cur->next = cur->next->next;
    23             cur = cur->next;
    24             if(ans->next){
    25                 ans->next = ans->next->next;
    26                 ans = ans->next;
    27             }
    28         }
    29         return copy;
    30     }
    31 };class Solution {
    32 public:
    33     Node* copyRandomList(Node* head) {
    34         if(head == nullptr)
    35             return nullptr;
    36         Node* cur = head;
    37         while(cur){
    38             Node* t = new Node(cur->val);
    39             t->next = cur->next;
    40             cur->next = t;
    41             cur = cur->next->next;
    42         }
    43         cur = head;
    44         while(cur){
    45                 cur->next->random = cur->random?cur->random->next:nullptr;//为啥是random->next,因为random要只向新生成的节点
    46                 cur = cur->next->next;
    47         }
    48         cur = head;
    49         Node *ans = head->next;
    50         Node *copy = head->next;
    51         while(cur){
    52             cur->next = cur->next->next;
    53             cur = cur->next;
    54             if(ans->next){
    55                 ans->next = ans->next->next;
    56                 ans = ans->next;
    57             }
    58         }
    59         return copy;
    60     }
    61 };
    View Code

     剑指 Offer 36. 二叉搜索树与双向链表 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     Node *head,*pre;
     4     Node* treeToDoublyList(Node* root) {
     5         if(root == nullptr)
     6             return root;
     7         dfs(root);
     8         head->left = pre;
     9         pre->right = head;
    10         return head;
    11     }
    12     void dfs(Node* cur){
    13         if(cur == nullptr)
    14             return ;
    15         dfs(cur->left);
    16         if(pre == nullptr){
    17             head = cur;
    18             cur->left = nullptr;
    19         }else{
    20             cur->left = pre;
    21             pre->right = cur;
    22         }
    23         pre = cur;
    24         dfs(cur->right);
    25     }
    26 };
    View Code

     剑指 Offer 38. 字符串的排列 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<string> result;
     4     string path;
     5     unordered_set<string> set;
     6     bool vis[10];
     7     void f(string s,int index){
     8         if(path.size()==s.size()-1){
     9             path.push_back(s[index]);
    10             if(set.count(path) == 0){
    11                 result.push_back(path);
    12                 set.insert(path);
    13             }
    14             path.pop_back();
    15             return ;
    16         }
    17         vis[index] = 1;
    18         path.push_back(s[index]);
    19         for(int i=0;i<s.size();i++){
    20             if(vis[i] == false){
    21                 f(s,i);
    22             }
    23             
    24         }
    25         vis[index] = 0;
    26         path.pop_back();
    27     }
    28     vector<string> permutation(string s) {
    29         for(int i=0;i<s.size();i++){
    30             f(s,i);
    31         }
    32         return result;
    33     }
    34 };
    View Code

     剑指 Offer 39. 数组中出现次数超过一半的数字 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int majorityElement(vector<int>& nums) {
     4         int n = nums.size();
     5         unordered_map<int,int> map;
     6         for(int i=0;i<n;i++){
     7             map[nums[i]]++;
     8             cout<<map[nums[i]];
     9             if(map[nums[i]]>n/2)
    10                 return nums[i];
    11         }
    12         return 0;
    13     }
    14 };
    View Code

     剑指 Offer 40. 最小的k个数 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     void qsort(vector<int>& arr,int l,int r){
     4         if(l>=r)
     5             return ;
     6         int cmp = l;
     7         int j = l;
     8         for(int i=l+1;i<=r;i++){
     9             if(arr[i]<arr[cmp]){
    10                 swap(arr[i],arr[++j]);
    11             }
    12         }
    13         swap(arr[cmp],arr[j]);
    14         qsort(arr,l,j-1);
    15         qsort(arr,j+1,r);
    16     }
    17     vector<int> getLeastNumbers(vector<int>& arr, int k) {
    18         qsort(arr,0,arr.size()-1);
    19         vector<int> ans;
    20         for(int i=0;i<k;i++)     
    21             ans.push_back(arr[i]);   
    22         return ans;
    23     }
    24 };
    View Code

     剑指 Offer 42. 连续子数组的最大和 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int maxSubArray(vector<int>& nums) {
     4         int ans = nums[0],sum = 0;
     5         for(int i=0;i<nums.size();i++){
     6             sum+=nums[i];
     7             ans = max(ans,sum);
     8             sum = max(sum,0);
     9         }
    10         return ans;
    11     }
    12 };
    View Code

     剑指 Offer 44. 数字序列中某一位的数字 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int findNthDigit(int n) {
     4         if(n<10)
     5             return n;
     6         long dp[20] = {1,10,190,2890,38890,488890,5888890,68888890,788888890,8888888890,98888888890};//190,2位数字最大是99,0~99加起来位数是190,10+90*2
     7         int sum = 0,x = n;
     8         for(int i=0;i<20;i++){//求出几位数,sum
     9             if(dp[i]>n){
    10                 sum = i;
    11                 break;
    12             }
    13         }
    14         int j = sum;
    15         int minn = 0;
    16         while(--j){//比如三位数,那么找到两位数最大值99
    17             minn = minn*10+9;
    18         }
    19         int count = (n-dp[sum-1]+1)%sum;  //dp数组表示的是有多少个数,n是从0开始的,所以0~n有n+1个数
    20         int number = minn+(n-dp[sum-1]+1)/sum;
    21         if(count == 0){
    22             string s = to_string(number);
    23             return s[s.size()-1]-'0';
    24         }else{
    25             string s = to_string(number+1);
    26             return s[count-1]-'0';//count表示第几个数,对应下标要减一
    27         }
    28         return 0;
    29     }
    30 };
    View Code

     剑指 Offer 45. 把数组排成最小的数 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     static bool cmp(string x,string y){
     4         return x+y<y+x;
     5     }
     6     string minNumber(vector<int>& nums) {
     7         vector<string>s;
     8         sort(nums.begin(),nums.end());
     9         for(int i=0;i<nums.size();i++){
    10             s.push_back(to_string(nums[i]));
    11         }
    12         sort(s.begin(),s.end(),cmp);
    13         string ans = "";
    14         for(int i=0;i<nums.size();i++){
    15             ans+=s[i];
    16         }
    17         return ans;
    18     }
    19 };
    View Code

     剑指 Offer 46. 把数字翻译成字符串 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int result;
     4     void f(string s,int index){
     5         if(index>=s.size()){
     6             result++;
     7             return ;
     8         }
     9         f(s,index+1);
    10         if(index+1<s.size()&&s[index]!='0'&&s.substr(index,2)<="25")//11,506
    11             f(s,index+2);
    12     }
    13     int translateNum(int num) {
    14         string s = to_string(num);
    15         f(s,0);
    16         return result;
    17     }
    18 };
    View Code

     剑指 Offer 47. 礼物的最大价值 - 力扣(LeetCode) (leetcode-cn.com)

    dp,以前这种二维矩阵都是dfs爆搜,现在学会dp了。

     1 class Solution {
     2 public:
     3     int maxValue(vector<vector<int>>& grid) {
     4         for(int i=0;i<grid.size();i++){
     5             for(int j=0;j<grid[0].size();j++){
     6                 if(i>0&&j>0){
     7                     grid[i][j] = max(grid[i-1][j],grid[i][j-1])+grid[i][j];
     8                 }else if(i>0){
     9                     grid[i][j] += grid[i-1][j];
    10                 }else if(j>0){
    11                     grid[i][j] += grid[i][j-1];
    12                 }
    13             }
    14         }
    15         return grid[grid.size()-1][grid[0].size()-1];
    16     }
    17 };
    View Code

     剑指 Offer 48. 最长不含重复字符的子字符串 - 力扣(LeetCode) (leetcode-cn.com)

    双指针加map

     1 class Solution {
     2 public:
     3     int lengthOfLongestSubstring(string s) {
     4         int n = s.size();
     5         if(n==0)
     6             return 0;
     7         vector<int> dp(n,1);
     8         unordered_map<char,int> map;
     9         dp[0] = 1;
    10         int ans = 1;
    11         map[s[0]] = 0;
    12         int j = 0;//合法子串的起始边界
    13         for(int i=1;i<n;i++){
    14             if(map.count(s[i]) == 0){
    15                 dp[i] = dp[i-1]+1;
    16             }else{
    17                 j = max(j,map[s[i]]+1);
    18                 cout<<"i="<<i<<" j="<<j<<endl;
    19                 dp[i] = i - j + 1;
    20             }
    21             map[s[i]] = i;
    22             ans = max(ans,dp[i]);
    23         }
    24         return ans;
    25     }
    26 };
    View Code

     剑指 Offer 49. 丑数 - 力扣(LeetCode) (leetcode-cn.com)

    想着除法判断丑数结果发现不行,原来是在已经是 丑数的基础上做有效乘法

     1 class Solution {
     2 public:
     3     int nthUglyNumber(int n) {
     4         vector<int> dp(n + 1);
     5         dp[1] = 1;
     6         int p2 = 1, p3 = 1, p5 = 1;
     7         for (int i = 2; i <= n; i++) {
     8             int num2 = dp[p2] * 2, num3 = dp[p3] * 3, num5 = dp[p5] * 5;
     9             dp[i] = min(min(num2, num3), num5);
    10             if (dp[i] == num2) {
    11                 p2++;
    12             }
    13             if (dp[i] == num3) {
    14                 p3++;
    15             }
    16             if (dp[i] == num5) {
    17                 p5++;
    18             }
    19         }
    20         return dp[n];
    21     }
    22 };
    View Code

     剑指 Offer 50. 第一个只出现一次的字符 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     char firstUniqChar(string s) {
     4         int a[26] = {0};
     5         for(int i=0;i<s.size();i++){
     6             a[s[i]-'a']++;
     7         }
     8         for(int i=0;i<s.size();i++){
     9             if(a[s[i]-'a']==1)
    10                 return s[i];
    11         }
    12         return ' ';
    13     }
    14 };
    View Code

     剑指 Offer 51. 数组中的逆序对 - 力扣(LeetCode) (leetcode-cn.com)

    官方题解初看没看懂,按思路应该是和下面代码一样,左边数大于右边数,右边数存入tmp数组,ans+=mid-i+1。意思是对于nums[j],左数组i之后mid之前这部分,都与之构成逆序对。

     1 class Solution {
     2 public:
     3     /* 合并有序数组 */
     4     int merge(vector<int>& nums, int left, int right) {
     5         int tmp[50050] = {0};
     6         int idx = 0;
     7         int mid = (left+right)/2;
     8         int i = left;
     9         int j = mid + 1;
    10         int ans = 0;
    11         while (i <= mid && j <= right) {
    12             if (nums[i] > nums[j]) {
    13                 ans += mid - i + 1; /* 统计逆序对 当前nums[i]往后的都比nums[j]大*/
    14                 tmp[idx++] = nums[j++];
    15             } else {
    16                 tmp[idx++] = nums[i++];
    17             }
    18         }
    19 
    20         /* 处理剩余数组 */
    21         while (i <= mid) {
    22             tmp[idx++] = nums[i++];
    23         }
    24         while (j <= right) {
    25             tmp[idx++] = nums[j++];
    26         }
    27 
    28         /* 写到原数组中 */
    29         for (int k = 0; k < idx; k++) {
    30             nums[left + k] = tmp[k];
    31         }
    32         return ans;
    33     }
    34 
    35     int mergeSort(vector<int>& nums, int l, int r) {
    36         if (l >= r) {
    37             return 0;
    38         }
    39         int m = (l+r)/2;
    40         int revCnt = mergeSort(nums, l, m) + mergeSort(nums, m + 1, r);
    41         return revCnt + merge(nums, l ,r);
    42     }
    43 
    44     int reversePairs(vector<int>& nums) {
    45         int n = nums.size();
    46         return mergeSort(nums, 0, n - 1);
    47     }
    48 };
    View Code

     剑指 Offer 52. 两个链表的第一个公共节点 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
     4         ListNode *HA = headA,*HB = headB;
     5         while(headA!=headB){
     6             headA = headA==nullptr?HB:headA->next;
     7             headB = headB==nullptr?HA:headB->next;
     8         }
     9         return headA;
    10     }
    11 };
    View Code

     剑指 Offer 53 - I. 在排序数组中查找数字 I - 力扣(LeetCode) (leetcode-cn.com)

    二分两次找左右边界

     1 class Solution {
     2 public:
     3     int search(vector<int>& nums, int target) {//两次二分,找边界
     4         int n = nums.size();
     5         if(n == 0)
     6             return 0;
     7         int l = 0,r = n-1;
     8         int right = -1;//没找到的保证答案为0
     9         while(l<=r){
    10             int mid = (l+r)/2;
    11             if(nums[mid] == target){
    12                 l = mid+1;
    13                 right = mid;
    14             }
    15             else if(nums[mid]<target){
    16                 l = mid+1;
    17                 
    18             }else{
    19                 r = mid-1;
    20             }
    21         }
    22         
    23         l = 0,r = n-1;
    24         int left = 0;
    25         while(l<=r){
    26             int mid = (l+r)/2;
    27             if(nums[mid] == target){
    28                 r = mid-1;
    29                 left = mid;
    30             }
    31             else if(nums[mid]>target){
    32                 r = mid-1;
    33             }else{
    34                 l = mid+1;
    35             }
    36         }
    37         // cout<<left<<right<<endl;
    38         return right-left+1;
    39     }
    40 };
    View Code

    二分一次,往左右延申

     1 class Solution {
     2 public:
     3     int search(vector<int>& nums, int target) {
     4         int n = nums.size();
     5         if(n == 0)
     6             return 0;
     7         int l = 0,r = n-1;
     8         while(l<=r){
     9             int mid = (l+r)/2;
    10             if(nums[mid] == target)
    11                 break;
    12             else if(nums[mid]<target){
    13                 l = mid+1;
    14             }else{
    15                 r = mid-1;
    16             }
    17         }
    18         int ans = 0;
    19         int mid1 = (l+r)/2,mid2 = (l+r)/2+1;
    20         while(mid1>=0&&nums[mid1] == target){
    21             ans++;
    22             mid1--;
    23         }
    24         while(mid2<n&&nums[mid2] == target){
    25             ans++;
    26             mid2++;
    27         }
    28         return ans;
    29     }
    30 };
    View Code

     剑指 Offer 53 - II. 0~n-1中缺失的数字 - 力扣(LeetCode) (leetcode-cn.com)

    特点,i = nums[i]

     1 class Solution {
     2 public:
     3     int missingNumber(vector<int>& nums) {
     4          int left = 0;
     5         int right = nums.size() - 1;
     6         while(left <= right) {
     7             int mid = (left + right) / 2;
     8             /* 如果相等说明 left 到 mid 中间肯定不少元素 所以往右边二分查找 */
     9             if(nums[mid] == mid) left = mid + 1;
    10             else right = mid - 1;
    11         }
    12         return left;
    13     }
    14 };
    View Code

     剑指 Offer 54. 二叉搜索树的第k大节点 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int ans;
     4     int num;
     5     void f(TreeNode* root){
     6         if(root == nullptr)
     7             return ;
     8         f(root->right);
     9         if(num == 1){
    10             ans = root->val;
    11             num--;
    12             return ;
    13         }
    14          num--;
    15         f(root->left);
    16         
    17         
    18     }
    19     int kthLargest(TreeNode* root, int k) {
    20         num = k;
    21         f(root);
    22         return ans;
    23     }
    24 };
    View Code

     剑指 Offer 55 - I. 二叉树的深度 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int f(TreeNode* root,int depth){
     4         if(root == nullptr)
     5             return depth;
     6         return max(f(root->left,depth),f(root->right,depth))+1;
     7     }
     8     int maxDepth(TreeNode* root) {
     9         return f(root,0);
    10     }
    11 };
    View Code

     剑指 Offer 56 - I. 数组中数字出现的次数 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<int> singleNumbers(vector<int>& nums) {
     4         int ret = 0;
     5         for (int x : nums)
     6             ret ^= x;
     7         int div = 1;
     8         while ((div & ret) == 0)
     9             div <<= 1;
    10         int a = 0, b = 0;
    11         for (int x : nums)
    12             if (div & x)
    13                 a ^= x;
    14             else
    15                 b ^= x;
    16         return vector<int>{a, b};
    17     }
    18 };
    View Code

     剑指 Offer 57. 和为s的两个数字 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<int> twoSum(vector<int>& nums, int target) {
     4         for(int i=0,j=nums.size()-1;i<nums.size()&&j>=i;){
     5             if(nums[i]+nums[j] == target){
     6                 return {nums[i],nums[j]};
     7             }else if(nums[i]<target-nums[j]){
     8                 i++;
     9             }else{
    10                 j--;
    11             }
    12         }
    13         return {};
    14     }
    15 };
    View Code

     剑指 Offer 57 - II. 和为s的连续正数序列 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<vector<int>> findContinuousSequence(int target) {
     4         vector<vector<int>> result;
     5         for(int i=1,j=2;i<j;){
     6             if((i+j)*(j-i+1)/2 == target){
     7                 vector<int> path;
     8                 for(int x=i;x<=j;x++)
     9                     path.push_back(x);
    10                 result.push_back(path);
    11                 //要执行i,j变化不然会超时
    12                 i++,j++;
    13             }else if((i+j)*(j-i+1)/2 < target){
    14                 j++;
    15             }else{
    16                 i++;
    17             }
    18         }
    19         return result;
    20     }
    21 };
    View Code

     剑指 Offer 58 - I. 翻转单词顺序 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     string reverseWords(string s) 
     4     {
     5         string res;
     6         for(int j = s.size() - 1; j >= 0; --j)
     7         {
     8             if(s[j] == ' ')
     9                 continue;
    10 
    11             int i = j;
    12             while(i >= 0 && s[i] != ' ') i--;
    13             res.append(s.substr(i + 1, j - i));
    14             res.append(" ");
    15             j = i;
    16         }
    17 
    18         if(!res.empty()) res.pop_back();
    19         return res;
    20     }
    21 };
    View Code

     剑指 Offer 58 - II. 左旋转字符串 - 力扣(LeetCode) (leetcode-cn.com)

    1 class Solution {
    2 public:
    3     string reverseLeftWords(string s, int n) {
    4         string ans = s.substr(n,s.size()-n);
    5         ans +=s.substr(0,n);
    6         return ans;
    7     }
    8 };
    View Code

      剑指 Offer 59 - I. 滑动窗口的最大值 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     vector<int> maxSlidingWindow(vector<int>& nums, int k) {//7 2 4     窗口过了,怎么弹出那个不在窗口的最大元素。以为队列里要存pair结构体,其实存i就行了,知i即nums[i]
     4         deque<int> que;
     5         vector<int> ans;
     6         for(int i=0;i<nums.size();i++){
     7             if(que.empty()){
     8                 que.push_back(i);
     9             }else if(nums[que.back()]<=nums[i]){
    10                 while(!que.empty()&&nums[que.back()]<=nums[i])
    11                     que.pop_back();
    12                 que.push_back(i);
    13             }else{
    14                 que.push_back(i);
    15             }
    16             if(i>=k){
    17                 if(que.front()<=i-k)
    18                     que.pop_front();
    19             }
    20             if(i>=k-1&&!que.empty()){
    21                 ans.push_back(nums[que.front()]);
    22             }
    23                 
    24         }
    25 
    26         return ans;
    27     }
    28 };
    View Code

     剑指 Offer 59 - II. 队列的最大值 - 力扣(LeetCode) (leetcode-cn.com)

     1 class MaxQueue {
     2 public:
     3     MaxQueue() {
     4     }
     5     queue<int> q;
     6     deque<int> d;
     7     int max_value() {
     8         if (d.empty())
     9             return -1;
    10         return d.front();
    11     }
    12     
    13     void push_back(int value) {
    14         while (!d.empty() && d.back() < value) {
    15             d.pop_back();
    16         }
    17         d.push_back(value);
    18         q.push(value);
    19     }
    20     
    21     int pop_front() {
    22         if (q.empty())
    23             return -1;
    24         int ans = q.front();
    25         if (ans == d.front()) {
    26             d.pop_front();
    27         }
    28         q.pop();
    29         return ans;
    30     }
    31 };
    View Code

     剑指 Offer 60. n个骰子的点数 - 力扣(LeetCode) (leetcode-cn.com)

    这个题,一是递归会超时,二是数据处理上,最后除以一个分母就行,初始化第一个骰子情况6个1

     1 class Solution {
     2 public:
     3     vector<double> twoSum(int n) {
     4         int dp[15][70];
     5         memset(dp, 0, sizeof(dp));
     6         for (int i = 1; i <= 6; i ++) {
     7             dp[1][i] = 1;
     8         }
     9         for (int i = 2; i <= n; i ++) {
    10             for (int j = i; j <= 6*i; j ++) {
    11                 for (int cur = 1; cur <= 6; cur ++) {
    12                     if (j - cur <= 0) {
    13                         break;
    14                     }
    15                     dp[i][j] += dp[i-1][j-cur];
    16                 }
    17             }
    18         }
    19         int all = pow(6, n);
    20         vector<double> ret;
    21         for (int i = n; i <= 6 * n; i ++) {
    22             ret.push_back(dp[n][i] * 1.0 / all);
    23         }
    24         return ret;
    25     }
    26 }; 
    View Code

     剑指 Offer 61. 扑克牌中的顺子 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     bool isStraight(vector<int>& nums) {
     4         sort(nums.begin(),nums.end());
     5         int all = 0;//表示大小王
     6         int sub = 0;
     7         for(int i = 0;i<nums.size();i++){//还有01123这情况
     8             if(nums[i]==0)
     9                 all++;
    10             else if(i>0&&nums[i-1]!=0&&nums[i]!=nums[i-1])
    11                 sub = sub+nums[i]-nums[i-1]-1;
    12             else if(i>0&&nums[i]==nums[i-1]){
    13                 return false;
    14             }
    15         }
    16         if(all>=sub)
    17             return true;
    18         else    
    19             return false;
    20     }
    21 };
    View Code

     剑指 Offer 63. 股票的最大利润 - 力扣(LeetCode) (leetcode-cn.com)

     1 class Solution {
     2 public:
     3     int maxProfit(vector<int>& prices) {
     4         int n =prices.size();
     5         if(n == 0)
     6             return 0;
     7         int mn = prices[0];
     8         int ans = 0;
     9         for(int i=1;i<n;i++){
    10             ans = max(ans,prices[i]-mn);
    11             mn = min(mn,prices[i]);
    12         }
    13         return ans;
    14     }
    15 };
    View Code

     剑指 Offer 68 - II. 二叉树的最近公共祖先 - 力扣(LeetCode) (leetcode-cn.com)

    左右子树都不空时返回根节点,否则返回左右子树不空那个

     1 class Solution {
     2 public:
     3     TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
     4         if(root == nullptr)
     5             return nullptr;
     6         if(root == p||root == q)
     7             return root;
     8         root->left = lowestCommonAncestor(root->left,p,q);
     9         root->right = lowestCommonAncestor(root->right,p,q);
    10         if(root->left&&root->right)
    11             return root;
    12         else
    13             root = root->left?root->left:root->right;
    14         return root;
    15     }
    16 };
    View Code
  • 相关阅读:
    爬虫的简单运用
    预测体育竞技比赛结果(新人练手)
    自己的第一个网页
    科学计算和可视化(numpy及matplotlib学习笔记)
    面向对象总结
    PIL库的总结及运用
    jirba库的使用和好玩的词云
    第一次结队作业
    四则运算版本升级
    自动生成小学四则运算项目练习(已更新)
  • 原文地址:https://www.cnblogs.com/hcl6/p/16000224.html
Copyright © 2020-2023  润新知