LeetCode

剑指offer 05.替换空格

class Solution {
public:
    string replaceSpace(string s) {
        string out;
        for(auto c:s)
        {
            if(c==' ')
            {
                out.push_back('%');
                out.push_back('2');
                out.push_back('0');
            }
            else
                out.push_back(c);
        }
        return out;

    }
};

剑指 Offer 58 - II. 左旋转字符串

#include<string>
#include<iostream>
using std::string;

string reverseLeftWords(string s, int n) {
        int size= s.size();
        string out=s;
        for(int i=0;i!=size;i++)
        {
            out[i]=s[(i+n)%size];
        }
        return out;
}

剑指 Offer 20. 表示数值的字符串

class Solution {
public:
    enum state{
        start,
        sign,
        intn,
        point,
        pointl,
        floatn,
        exp,
        expn,
        expsign,
        end
    };
    enum c{
        spacec,
        signc,
        numc,
        pointc,
        expc,
        otherc
    };

    c toc(char s)
    {
        if(s<='9'&&s>='0')
            return numc;
        else if(s==' ')
            return spacec;
        else if(s=='+'||s=='-')
            return signc;
        else if(s=='.')
            return pointc;
        else if(s=='e'||s=='E')
            return expc;
        else
            return otherc;
    }

    unordered_map<state,unordered_map<c,state>> our=
    {
        {start,{{spacec,start},{pointc,point},{signc,sign},{numc,intn}}},
        {sign,{{numc,intn},{pointc,point}}},
        {point,{{numc,floatn}}},
        {intn,{{numc,intn},{pointc,pointl},{expc,exp},{spacec,end}}},
        {pointl,{{numc,floatn},{expc,exp},{spacec,end}}},
        {floatn,{{expc,exp},{spacec,end},{numc,floatn}}},
        {exp,{{signc,expsign},{numc,expn}}},
        {expsign,{{numc,expn}}},
        {expn,{{numc,expn},{spacec,end}}},
        {end,{{spacec,end}}}
    };

    bool isNumber(string s) {
        state t=start;

        for(int i=0;i!=s.size();i++)
        {
            c now = toc(s[i]);
            if(our[t].find(now)==our[t].end())
                return false;
            else{
                t=our[t][now];
            }

        }
        if(t==intn||t==pointl||t==floatn||t==expn||t==end)
            return true;
        else
            return false;
    }
};

剑指 Offer 67. 把字符串转换成整数

class Solution {
public:
    enum state{
        start,
        sign,
        intn,
        none,
        end
    };
    enum c{
        spacec,
        signc,
        numc,
        otherc
    };
    c toc(char s)
    {
        if(s<='9'&&s>='0')
            return numc;
        else if(s==' ')
            return spacec;
        else if(s=='+'||s=='-')
            return signc;
        else
            return otherc;
    }
    unordered_map<state,unordered_map<c,state>>our
    {
        {start,{{spacec,start},{signc,sign},{numc,intn},{otherc,none}}},
        {sign,{{spacec,none},{signc,none},{numc,intn},{otherc,none}}},
        {intn,{{spacec,end},{signc,end},{numc,intn},{otherc,end}}},
        {none,{{spacec,none},{signc,none},{numc,none},{otherc,none}}},
        {end,{{spacec,end},{signc,end},{numc,end},{otherc,end}}}
    };
    int strToInt(string str) {
        state t=start;
        string s;
        int signbit=1;
        for(int i=0;i!=str.size();i++)
        {
            t = our[t][toc(str[i])];
            if(t==sign)
                signbit=str[i]=='-'?-1:1;
            else if(t==intn)
                s.push_back(str[i]);
        }

        int st=0;
        for(int i=0;i!=s.size();i++)
        {
            if(s[i]=='0')
                st++;
            else 
                break;
        }

        if(t==intn||t==end)
        {
        long long out=0;
        long long lobe = 1;
        long long limit = signbit==1?INT_MAX:INT_MIN;
        if(s.size()-st>10)
            return limit;
        for(int i=s.size()-1;i>=st;i--)
        {
            out+=(s[i]-'0')*lobe;
            lobe*=10;
            if(signbit==1&&limit<out)
            {
                return INT_MAX;
            }
            else if(signbit==-1&&limit>-out)
            {
                return INT_MIN;
            }
        }
        out*=signbit;
        return out;
        }
        else 
            return 0;
    }
};

剑指 Offer 06. 从尾到头打印链表

//交换
class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int> re;
        while(head)
        {
            re.push_back(head->val);
            head=head->next;
        }
        for(int i=0;i!=re.size()/2;i++)
        {
            swap(re[i],re[re.size()-i-1]);
        }
        return re;

    }
};
//栈
class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int> re;
        stack<int> st;
        while(head)
        {
            st.push(head->val);
            head=head->next;
        }
        while(!st.empty())
        {
            re.push_back(st.top());
            st.pop();
        }
        return re;

    }
};

剑指 Offer 24. 反转链表

//迭代
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* last=nullptr;
        ListNode* step=nullptr;
        while(head)
        {
            step=head->next;
            head->next=last;
            last=head;
            head=step;
            
        }
        return last;

    }
};
//递归
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head||!head->next)
            return head;
        
        
        ListNode* out =  reverseList(head->next);
        head->next->next=head;
        head->next=nullptr;

        return out;

    }
};

剑指 Offer 35. 复杂链表的复制

//哈希表
class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(!head)
            return nullptr;

        unordered_map<Node*,Node*>n;
        Node* out=new Node(0);
        Node* p=out;
        while(head)
        {
            p->next = new Node(head->val);
            p->next->next=nullptr;
            p->next->random=head->random;

            n[head]=p->next;
            p=p->next;
            head=head->next;
        }
        n[nullptr]=nullptr;
        p=out->next;
        while(p)
        {
            p->random=n[p->random];
            p=p->next;
        }
        return out->next;
    }
};
//节点拆分
class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(!head)
            return nullptr;
        for(Node* i=head;i!=nullptr;i=i->next->next)
        {
            Node* newNode = new Node(i->val);
            newNode->next=i->next;
            i->next=newNode;
        }
        for(Node*i=head;i!=nullptr;i=i->next->next)
        {
            i->next->random=(i->random==nullptr)?nullptr:i->random->next;
        }
        Node* outNode = head->next;
        for(Node*i=head;i!=nullptr;i=i->next)
        {
            Node* newNode = i->next;
            i->next=newNode->next;
            newNode->next=(newNode->next==nullptr)?nullptr:newNode->next->next; 
        }
        return outNode;
    }
};

剑指 Offer 18. 删除链表的节点

//双指针
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if(!head)
            return nullptr;
        if(head->val==val)
            return head->next;
        ListNode* last=head;
        for(ListNode*i=head->next;i!=nullptr;i=i->next)
        {
            if(i->val==val)
            {
                last->next=i->next;
                return head;
            }
            else
            {
                last=i;
            }
        }
        return head;
    }
};

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

//双指针
class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        ListNode* p=head;
        for(int i=1;i<=k;i++)
        {
            p=p->next;
        }
        while(p)
        {
            head=head->next;
            p=p->next;
        }
        return head;

    }
};

剑指 Offer 25. 合并两个排序的链表

//递归
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(!l1)
            return l2;
        else if(!l2)
            return l1;
        else if(l1->val<l2->val)
        {
            l1->next=mergeTwoLists(l1->next,l2);
            return l1;
        }
        else
        {
            l2->next=mergeTwoLists(l2->next,l1);
            return l2;
        }

    }
};
//迭代
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* head=new ListNode(0);
        ListNode* p=head;
        while(l1&&l2)
        {
            if(l1->val<l2->val)
            {
                p->next=l1;
                l1=l1->next;
            }
            else
            {
                p->next=l2;
                l2=l2->next;
            }
            p=p->next;
            
        }
        if(l1)
            p->next=l1;
        else if(l2)
            p->next=l2;
        
        return head->next;

    }
};

剑指 Offer 52. 两个链表的第一个公共节点

//哈希表
class Solution {
public:
    unordered_set<ListNode*>s;
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        while(headA)
        {
            s.insert(headA);
            headA=headA->next;
        }
        while(headB)
        {
            if(s.find(headB)!=s.end())
                break;
            headB=headB->next;
        }
        return headB;
    }
};
//双指针
class Solution {
public:
    unordered_set<ListNode*>s;
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* pa=headA;
        ListNode* pb=headB;

        while(pa!=pb)
        {
            pa=(pa==nullptr)?headA:pa->next;
            pb=(pb==nullptr)?headB:pb->next;
        }
        return pa;
    }
};

剑指 Offer 53 - I. 在排序数组中查找数字 I

//顺序查找
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int num=0;
        for(int i=0;i!=nums.size();i++)
        {
            if(nums[i]==target)
                num++;
        }
        return num;

    }
};
//二分查找
class Solution {
public:
    int bs(vector<int>& nums, int target, bool low)
    {
        int left = 0, right = nums.size()-1,ans=nums.size();

        while(left<=right)
        {
            int mid=(left+right)/2;
            if(nums[mid]>target||(nums[mid]>=target&&low))
            {
                right=mid-1;
                ans=mid;
            }
            else
            {
                left=mid+1;
            }
        }
        return ans;
    }
    int search(vector<int>& nums, int target) {
        int left = bs(nums,target,true);
        int right = bs(nums,target,false);
        return right-left;
    }
};

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

//双指针
class Solution {
public:
    vector<int> exchange(vector<int>& nums) {
        int i=0,j=nums.size()-1;
        while(i<j)
        {
            while(i<j && nums[i]%2==1)
                i++;
            while(i<j && nums[j]%2==0)
                j--;
            swap(nums[i],nums[j]);
        }
        return nums;

    }
};

剑指 Offer 57. 和为s的两个数字

//双指针
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int i=0,j=nums.size()-1;
        vector<int>ans;
        while(i<j)
        {
            while(i<j && nums[i]+nums[j]>target)
            {
                j--;
            }
            while(i<j && nums[i]+nums[j]<target)
            {
                i++;
            }
            if(i<j && nums[i]+nums[j]==target)
                {
                    ans={nums[i],nums[j]};
                    break;
                }
        }
        return ans;
    }
};

剑指 Offer 58 - I. 翻转单词顺序

//栈
class Solution {
public:
    string reverseWords(string s) {
        stack<string>st;
        string out;
        for(auto c:s)
        {
            if(c==' ' && out.size()!=0)
            {
                st.push(out);
                out="";
            }
            else if(c!=' ')
            {
                out.push_back(c);
            }
        }
        if(out.size()!=0)
        {
            st.push(out);
        }
        string ans;
        while(!st.empty())
        {
            ans+=st.top();
            st.pop();
            if(!st.empty())
            {
                ans.push_back(' ');
            }
        }
        return ans;

    }
};

剑指 Offer 09. 用两个栈实现队列

class CQueue {
public:
    stack<int>temp;
    stack<int>out;

    CQueue() {

    }
    
    void appendTail(int value) {
        temp.push(value);
    }
    
    int deleteHead() {
        int ans;
        if(!out.empty())
        {
            ans = out.top();
            out.pop();
        }
        else if(!temp.empty())
        {
            while(!temp.empty())
            {
                out.push(temp.top());
                temp.pop();
            }
            ans=out.top();
            out.pop();
        }
        else
        {
            ans=-1;
        }


        return ans;
    }
};

剑指 Offer 30. 包含min函数的栈

//辅助栈
class MinStack {
public:
    /** initialize your data structure here. */
    stack<int>st;
    stack<int>minst;
    MinStack() {
        minst.push(INT_MAX);

    }
    
    void push(int x) {
        st.push(x);
        minst.push(x<minst.top()?x:minst.top());

    }
    
    void pop() {
        st.pop();
        minst.pop();

    }
    
    int top() {
        return st.top();

    }
    
    int min() {
        return minst.top();
    }
};

剑指 Offer 59 - I. 滑动窗口的最大值

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        if(nums.size()==0)
        {
            return {};
        }
        deque<int>q;
        vector<int>ans;

        int l=1-k,r=0;
        while(r<nums.size())
        {
            if(l>=1 && q[0]==nums[l-1])
            {
                q.pop_front();
            }
            while(!q.empty()&&q[q.size()-1]<nums[r]) q.pop_back();
            q.push_back(nums[r]);

            if(l>=0)
            {
                ans.push_back(q[0]);
            }
            l++;r++;
        }
        return ans;

    }
};

剑指 Offer 59 - II. 队列的最大值

//单调双端队列
class MaxQueue {
public:
    deque<int>maxque;
    deque<int>outque;
    MaxQueue() {

    }
    
    int max_value() {
        if(outque.empty()) return -1;
        return maxque[0];

    }
    
    void push_back(int value) {
        while(!maxque.empty() && maxque[maxque.size()-1]<value) maxque.pop_back();
        maxque.push_back(value);
        outque.push_back(value);
    }
    
    int pop_front() {
        if(outque.empty()) return -1;
        if(outque[0]==maxque[0])
        {
            maxque.pop_front();
        }
        int ans = outque[0];
        outque.pop_front();
        return ans;

    }
};

剑指 Offer 29. 顺时针打印矩阵

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if(matrix.size()==0)
            return {};
        if(matrix[0].size()==0)
            return {};
        vector<int>ans;
        int i=0,j=0;
        int l=0,r=matrix[0].size()-1,u=0,d=matrix.size()-1;
        while(ans.size()<matrix.size()*matrix[0].size())
        {
            while(ans.size()<matrix.size()*matrix[0].size()&&j<=r)
            {
                ans.push_back(matrix[i][j]);
                if(j<r) j++;
                else 
                {
                    i++;
                    u++; 
                    break;
                }
            }
            while(ans.size()<matrix.size()*matrix[0].size()&&i<=d)
            {
                ans.push_back(matrix[i][j]);
                if(i<d) i++;
                else
                {
                    j--;
                    r--;
                    break;
                }
            }
            while(ans.size()<matrix.size()*matrix[0].size()&&j>=l)
            {
                ans.push_back(matrix[i][j]);
                if(j>l) j--;
                else 
                {
                    i--;
                    d--; 
                    break;
                }
            }
            while(ans.size()<matrix.size()*matrix[0].size()&&i>=u)
            {
                ans.push_back(matrix[i][j]);
                if(i>u) i--;
                else
                {
                    j++;
                    l++;
                    break;
                }
            }
        }
        return ans;

    }
};

剑指 Offer 31. 栈的压入、弹出序列

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        unordered_set<int>s;
        stack<int>in;
        int i=0,j=0;
        while(j<popped.size())
        {
            while(s.find(popped[j])==s.end())
            {
                in.push(pushed[i]);
                s.insert(pushed[i]);
                i++;
            }
            if(in.top()==popped[j])
            {
                in.pop();
                j++;
            }
            else
            {
                return false;
            }
        }
        return true;
    }
};
class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int>in;
        int j =0;
        for(int i=0;i!=pushed.size();i++)
        {
            in.push(pushed[i]);
            while(j<popped.size() && !in.empty() && in.top()==popped[j])
            {
                in.pop();
                j++;
            }
        }
        if(in.empty()) return true;
        else return false;

    }
};

剑指 Offer 03. 数组中重复的数字

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        unordered_set<int>s;
        int ans;
        for(auto n: nums)
        {
            if(s.find(n)==s.end())
            {
                s.insert(n);
            }
            else
            {
                ans = n;
                break;
            }
                
        }
        return ans;
    }
};
class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int i=0;
        int ans;
        while(i<nums.size())
        {
            if(nums[i]==i)
            {
                i++;
                continue;
            }
            if(nums[i]==nums[nums[i]])
            {
                ans=nums[i];
                break;
            }
            else
            {
                swap(nums[i],nums[nums[i]]);
            }
            
        }
        return ans;
    }
};

剑指 Offer 53 - II. 0~n-1中缺失的数字

//二分查找
class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int i=0,j=nums.size()-1,mid;
        while(i<=j)
        {
            mid=(i+j)/2;
            if(nums[mid]>mid)
            {
                j=mid-1;
            }
            else
            {
                i=mid+1;
            }
        }
        return j+1;

    }
};

剑指 Offer 04. 二维数组中的查找

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


    }
};

剑指 Offer 11. 旋转数组的最小数字

class Solution {
public:
    int minArray(vector<int>& numbers) {
        int l=0,r=numbers.size()-1;
        int length = numbers.size();
        int ans;
        int st=0;
        int k=1;
        while(numbers[st]==numbers[(st-1+length)%length] && k<length) 
        {
            k++;
            st++;
        }
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(numbers[(st+mid)%length]<numbers[(st+mid-1+length)%length])
            {
                ans= numbers[(st+mid)%length];
                break;
            }
            else if(numbers[(st+mid)%length]<=numbers[(st+length-1)%length])
            {
                r=mid-1;
            }
            else{
                l=mid+1;
            }

        }
        return ans;

    }
};

剑指 Offer 50. 第一个只出现一次的字符

class Solution {
public:
    char firstUniqChar(string s) {
        unordered_map<char,int> set;
        deque<char>dq;
        for(auto c:s)
        {
            set[c]++;
            dq.push_back(c);
            while(!dq.empty()&&set.at(dq[0])!=1) dq.pop_front();
        }
        if(dq.empty()) return ' ';
        else return dq[0]; 

    }
};

剑指 Offer 32 - I. 从上到下打印二叉树

//广度优先搜索
class Solution {
public:
    vector<int> levelOrder(TreeNode* root) {
        if(!root) return {};
        deque<TreeNode*>dq;
        vector<int>ans;
        dq.push_back(root);
        while(!dq.empty())
        {
            ans.push_back(dq[0]->val);
            if(dq[0]->left) dq.push_back(dq[0]->left);
            if(dq[0]->right) dq.push_back(dq[0]->right);
            dq.pop_front();
        }
        return ans;

    }
};

剑指 Offer 32 - II. 从上到下打印二叉树 II

//广度优先搜索
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(!root) return {};
        deque<TreeNode*>dq;
        vector<vector<int>>ans;
        dq.push_back(root);

        while(!dq.empty())
        {
            vector<int> temp;
            for(auto c: dq)
            {
                temp.push_back(c->val);
            }
            ans.push_back(temp);
            for(int i=0;i!=temp.size();i++)
            {
                if(dq[0]->left) dq.push_back(dq[0]->left);
                if(dq[0]->right) dq.push_back(dq[0]->right);
                dq.pop_front();
            }
        }
        return ans;

    }
};

剑指 Offer 32 - III. 从上到下打印二叉树 III

//广度优先搜索
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(!root) return {};
        deque<TreeNode*>dq;
        vector<vector<int>>ans;
        dq.push_back(root);
        int re=false;

        while(!dq.empty())
        {
            vector<int> temp;
            for(auto c: dq)
            {
                temp.push_back(c->val);
            }
            if(re) reverse(temp.begin(),temp.end());
            ans.push_back(temp);
            re=!re;
            for(int i=0;i!=temp.size();i++)
            {
                if(dq[0]->left) dq.push_back(dq[0]->left);
                if(dq[0]->right) dq.push_back(dq[0]->right);
                dq.pop_front();
            }
        }
        return ans;

    }
};

剑指 Offer 26. 树的子结构

//先序遍历
class Solution {
public:
    bool isSub(TreeNode* A, TreeNode* B, bool r) {
        if(!B) return false;
        if(!A) return false;
        if(A->val==B->val)
        {
            return (!B->left || isSub(A->left,B->left, false))&& (!B->right||isSub(A->right,B->right,false))||r&&(isSub(A->left,B,r) || r&&isSub(A->right,B,r));
        }
        else
        {
            return r&&(isSub(A->left,B,r) || isSub(A->right,B,r));
        }
    }
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        return isSub(A,B,true);

    }

};

剑指 Offer 27. 二叉树的镜像

//先序遍历
class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if(!root) return nullptr;
        TreeNode* newNode = root->left;
        root->left=root->right;
        root->right=newNode;
        mirrorTree(root->left);
        mirrorTree(root->right);
        return root;
    }
};

剑指 Offer 28. 对称的二叉树

//广度优先搜索
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        deque<TreeNode*>dq;
        dq.push_back(root);
        while(!dq.empty())
        {
            vector<int> ans;
            int len = dq.size();
            for(int i=0;i!=len;i++)
            {
                if(dq[i])
                    ans.push_back(dq[i]->val);
                else
                    ans.push_back(-1);
            }
            vector<int>ano=ans;
            reverse(ans.begin(),ans.end());
            if(ano!=ans)
            {
                return false;
            }
            for(int i=0;i!=len;i++)
            {
                if(dq[0])
                {
                    dq.push_back(dq[0]->left);
                    dq.push_back(dq[0]->right);
                }
                dq.pop_front();

            }

        }
        return true;


    }
};
//递归
class Solution {
public:
    bool isS(TreeNode* l,TreeNode* r)
    {
        if(!l&&!r) return true;
        else if(!l||!r) return false;

        if(l->val==r->val)
        {
            return isS(l->left,r->right) && isS(l->right, r->left);
        }
        else
        {
            return false;
        }
    }
    bool isSymmetric(TreeNode* root) {
        if(!root) return true;
        return isS(root->left,root->right);
 
    }
};

剑指 Offer 12. 矩阵中的路径

//回溯
class Solution {
public:
    bool fi(vector<vector<char>>& board, string word, int k, int i, int j)
    {
        if(board[i][j]!=word[k]) return false;
        if(k==word.size()-1) return true;
        char now=board[i][j];
        board[i][j]=' ';
        int I=board.size()-1,J=board[0].size()-1;
        bool ans;
        if(i-1>=0 && fi(board,word,k+1,i-1,j))
        {
            return true;
        }
        if(i+1<=I&&fi(board,word,k+1,i+1,j))
        {
            return true;
        }

        if(j-1>=0&&fi(board,word,k+1,i,j-1))
        {
            return true;
        }

        if(j+1<=J&&fi(board,word,k+1,i,j+1))
        {
            return true;
        }
        board[i][j]=now;
        return false;
    }
    bool exist(vector<vector<char>>& board, string word) {
        for(int i=0;i!=board.size();i++)
        {
            for(int j=0;j!=board[0].size();j++)
            {
                if(fi(board,word,0,i,j))
                {
                    return true;
                }
            }
        }
        return false;
    }
};

剑指 Offer 13. 机器人的运动范围

//哈希表 回溯
class Solution {
public:
    unordered_set<int>set;
    void mo(int m,int n, int k, int i, int j)
    {
        if(set.find(i*n+j)!=set.end())
            return;
        int a= i/100+(i%100)/10+i%10;
        int b = j/100+(j%100)/10+j%10;
        if(a+b>k) return;


        set.insert(i*n+j);
        

        if(i+1<m)
            mo(m,n,k,i+1,j);
        if(j+1<n)
            mo(m,n,k,i,j+1);
        return;
    }
    int movingCount(int m, int n, int k) {
        mo(m,n,k,0,0);
        return set.size();

    }
};
//哈希表 广度优先搜索
class Solution {
public:
    unordered_set<int>set;
    deque<pair<int,int>>dq;
    int get(int x,int y)
    {
        int a =x%10+x/10%10+x/100%10;
        int b =y%10+y/10%10+y/100%10;
        return a+b;
    }
    int movingCount(int m, int n, int k) {
        dq.push_back(make_pair(0,0));
        set.insert(0);
        int ans=0;
        while(!dq.empty())
        {
            ans++;
           
            auto [x,y]=dq[0];
            
            if(x+1<m && set.find((x+1)*n+y)==set.end() && get(x+1,y)<=k)
            {
                dq.push_back(make_pair(x+1,y));
                set.insert((x+1)*n+y);
            }
            if(y+1<n && set.find(x*n+y+1)==set.end() && get(x,y+1)<=k)
            {
                dq.push_back(make_pair(x,y+1));
                set.insert(x*n+y+1);
            }
            dq.pop_front();

        }
        return ans;

    }
};
//递推
class Solution {
public:
    int get(int x,int y)
    {
        int a =x%10+x/10%10+x/100%10;
        int b =y%10+y/10%10+y/100%10;
        return a+b;
    }
    int movingCount(int m, int n, int k) {
        int ans=1;
        vector<vector<int>>out(m,vector<int>(n,0));
        out[0][0]=1;
        for(int i=0;i!=m;i++)
        {
            for(int j=0;j!=n;j++)
            {
                if(i==0&&j==0) continue;
                if(i-1>=0&&out[i-1][j]==1 || j-1>=0&&out[i][j-1]==1)
                {
                    if(get(i,j)<=k) 
                    {
                        out[i][j]=1;
                        ans++;
                    }
                }
            }
        }
        return ans;

    }
};

剑指 Offer 34. 二叉树中和为某一值的路径

//深度优先搜索
class Solution {
public:
    vector<vector<int>>ans;
    vector<int>path;
    void dfs(TreeNode* r, int target)
    {
        if(!r) return;
        path.push_back(r->val);

        if(!r->left && !r->right && r->val==target) 
        {
            ans.push_back(path);
        }
        

        dfs(r->left,target-r->val);
        dfs(r->right,target-r->val);

        path.pop_back();
        return;

    }
    vector<vector<int>> pathSum(TreeNode* root, int target) {
        dfs(root,target);
        return ans;


    }
};

剑指 Offer 36. 二叉搜索树与双向链表

//中序遍历
class Solution {
public:
    pair<Node*,Node*> fs(Node* r)
    {
        if(!r->left && !r->right) return make_pair(r,r);
        Node* lo;
        Node* ro;
        if(r->left)
        {
            auto [l1,r1] = fs(r->left);
            r1->right = r;
            r->left = r1;
            lo=l1;

        }
        else
        {
            lo=r;
        }
        
        if(r->right)
        {
            auto [l2,r2] = fs(r->right);
            l2->left = r;
            r->right = l2;
            ro=r2;
        }
        else{
            ro=r;
        }

        return make_pair(lo,ro);
    }
    Node* treeToDoublyList(Node* root) {
        if(!root)
            return nullptr;
        auto [start, end] = fs(root);
        start->left=end;
        end->right=start;
        return start;
    }
};
//中序遍历
class Solution {
public:
    Node* head=nullptr,*pre=nullptr;
    void dfs(Node* r)
    {
        if(!r)return;
        dfs(r->left);

        if(!pre)
        {
            head=r;
        }
        else
        {
            pre->right=r;
            
        }
        r->left=pre;
        pre=r;

        dfs(r->right);
        return;
    }
    Node* treeToDoublyList(Node* root) {
        if(!root)
            return nullptr;
        dfs(root);
        head->left=pre;
        pre->right=head;
        return head;
    }
};

剑指 Offer 54. 二叉搜索树的第k大节点

//中序遍历(反向)
class Solution {
public:
    int n=0;
    int ans;
    void dfs(TreeNode* r, int k)
    {
        if(!r) return;
        dfs(r->right,k);

        n++;
        if(n==k)
        {
            ans=r->val;
            return;
        }
        else if(n>k) return;

        dfs(r->left,k);
    }
    int kthLargest(TreeNode* root, int k) {
        dfs(root,k);
        return ans;

    }
};

剑指 Offer 55 - I. 二叉树的深度

//后序遍历
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root) return 0;
        int l=maxDepth(root->left);
        int r=maxDepth(root->right);
        return max(l,r)+1;
    }
};

剑指 Offer 55 - II. 平衡二叉树

//后序遍历
class Solution {
public:
    int dfs(TreeNode* r)
    {
        if(!r) return 0;
        int lo=dfs(r->left);
        int ro=dfs(r->right);
        if(lo==-1 || ro==-1) return -1;
        if(abs(lo-ro)>1) 
            return -1;
        return max(lo,ro)+1;
    }
    bool isBalanced(TreeNode* root) {
        int out = dfs(root);
        return out==-1?false:true;

    }
};

剑指 Offer 64. 求1+2+…+n

//逻辑符短路
class Solution {
public:
    int ans=0;
    int sumNums(int n) {
        (n>1) && sumNums(n-1);
        ans+=n;
        return ans;

    }
};
//构造函数
class Solution {
public:
    static int ans;
    static int index;
    Solution()
    {
        index++;
        ans+=index;
    }
    void clear()
    {
        ans=0;
        index=0;
    }
    int sumNums(int n) {
        clear();
        Solution* x=new Solution[n];
        return ans;
    }
};

int Solution::ans=0;
int Solution::index=0;

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

//先序遍历
class Solution {
public: 
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root) return nullptr;
        TreeNode* t1=p->val<q->val?p:q;
        TreeNode* t2=p->val<q->val?q:p;
        if(root->val>=t1->val && root->val<=t2->val) return root;
        else if(root->val<t1->val) return lowestCommonAncestor(root->right,t1,t2);
        else return lowestCommonAncestor(root->left,t1,t2);       
    }
};

剑指 Offer 68 - II. 二叉树的最近公共祖先

//后序遍历
class Solution {
public:
    TreeNode* out;
    int dfs(TreeNode* r, TreeNode* p, TreeNode* q)
    {
        if(!r) return 0;

        int a1 = dfs(r->left,p,q);
        int a2 = dfs(r->right,p,q);
        if(a1==2||a2==2) return 2;

        int ans=a1+a2;
        if(r->val==p->val||r->val==q->val)
        {
            ans+=1;
        }
        if(ans==2) out=r;
        return ans;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        int n=dfs(root,p,q);
        return out;
    }
};
//后序遍历
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(!root||root==p||root==q) return root;
        
        TreeNode* t1 = lowestCommonAncestor(root->left,p,q);
        TreeNode* t2 = lowestCommonAncestor(root->right,p,q);

        if(!t1&&!t2) return nullptr;
        else if(!t1 && t2) return t2;
        else if(t1 && !t2) return t1;
        else return root;
    }
};

剑指 Offer 37. 序列化二叉树

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        deque<TreeNode*>dq;
        dq.push_back(root);
        ostringstream out;
        while(!dq.empty())
        {
            if(dq[0])
            {
                dq.push_back(dq[0]->left);
                dq.push_back(dq[0]->right);
            }
            if(dq[0])
                out<<dq[0]->val<<' ';
            else
                out<<"NULL ";
            dq.pop_front();
        }
        return out.str();
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        vector<TreeNode*> ans;
        istringstream in(data);
        string s;
        while(in>>s)
        {
            if(s=="NULL") ans.push_back(nullptr);
            else
            {
                TreeNode* node = new TreeNode(stoi(s));
                ans.push_back(node);
            }
        }
        int index=1;
        for(int i=0;i!=ans.size();i++)
        {
            if(ans[i])
            {
                ans[i]->left=ans[index++];
                ans[i]->right=ans[index++];
            }
        }
        return ans[0];

        
    }
};

剑指 Offer 38. 字符串的排列

class Solution {
public:
    unordered_set<int>set;
    unordered_set<string> ans;
    string out;
    void fs(string s,int c)
    {
        if(set.find(c)!=set.end()) return;
        set.insert(c);
        out.push_back(s[c]);
        if(out.size()==s.size()) 
        {
            ans.insert(out);
        }
        else
        {
            for(int i=0;i!=s.size();i++)
            {
                fs(s,i);
            }
        }
        out.pop_back();
        set.erase(c);
    }
    vector<string> permutation(string s) {
        for(int i=0;i!=s.size();i++)
        {
            fs(s,i);
        }
        vector<string>out;
        for(auto c:ans)
            out.push_back(c);
        return out;

    }
};

剑指 Offer 38. 字符串的排列

//回溯
class Solution {
public:
    unordered_set<int>set;
    unordered_set<string> ans;
    string out;
    void fs(string s,int c)
    {
        if(set.find(c)!=set.end()) return;
        set.insert(c);
        out.push_back(s[c]);
        if(out.size()==s.size()) 
        {
            ans.insert(out);
        }
        else
        {
            for(int i=0;i!=s.size();i++)
            {
                fs(s,i);
            }
        }
        out.pop_back();
        set.erase(c);
    }
    vector<string> permutation(string s) {
        for(int i=0;i!=s.size();i++)
        {
            fs(s,i);
        }
        vector<string>out;
        for(auto c:ans)
            out.push_back(c);
        return out;

    }
};

剑指 Offer 07. 重建二叉树

class Solution {
public:
    TreeNode* fs(vector<int>& preorder, vector<int>& inorder, int l1, int r1, int l2, int r2)
    {
        if(l1>r1) return nullptr;
        
        TreeNode* node=new TreeNode(preorder[l1]);
        if(l1==r1) return node;

        int temp;
        for(temp=l2;temp<=r2;temp++)
        {
            if(inorder[temp]==preorder[l1])
            {
                break;
            }
        }
        int length = temp-l2;

        node->left=fs(preorder,inorder,l1+1,l1+length,l2,temp-1);
        node->right=fs(preorder,inorder,l1+length+1,r1,temp+1,r2);
        return node;

    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return fs(preorder,inorder,0,preorder.size()-1,0,preorder.size()-1);

    }
};
//哈希表映射位置
class Solution {
public:
    unordered_map<int ,int>map;
    TreeNode* fs(vector<int>& preorder, vector<int>& inorder, int l1, int r1, int l2, int r2)
    {
        if(l1>r1) return nullptr;
        
        TreeNode* node=new TreeNode(preorder[l1]);
        if(l1==r1) return node;

        int temp=map.at(preorder[l1]);
        int length = temp-l2;

        node->left=fs(preorder,inorder,l1+1,l1+length,l2,temp-1);
        node->right=fs(preorder,inorder,l1+length+1,r1,temp+1,r2);
        return node;

    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for(int i=0;i!=inorder.size();i++)
        {
            map[inorder[i]]=i;
        }
        return fs(preorder,inorder,0,preorder.size()-1,0,preorder.size()-1);

    }
};

剑指 Offer 16. 数值的整数次方

//快速乘
class Solution {
public:
    double myPow(double x, long long n) {
        if(n==0) return 1.0;
        long long p=n>0?n:-n;
        double ans=1;
        while(p>0)
        {
            if(p&1)
            {
                ans*=x;
            }
            x*=x;
            p>>=1;
        }
        return n<0?1.0/ans:ans;
    }
};

剑指 Offer 33. 二叉搜索树的后序遍历序列

//分治
class Solution {
public:
    bool fs(vector<int>& postorder,int l,int r)
    {
        if(l>=r) return true;
        int root=postorder[r];
        int temp=-1;
        for(int i=r-1;i>=l;i--)
        {
            if(temp==-1 && postorder[i]<root)
            {
                temp=i;
            }
            else if(temp!=-1 && postorder[i]>root)
            {
                return false;
            }
        }
        if(temp==-1) temp=l-1;

        return fs(postorder,l,temp)&&fs(postorder,temp+1,r-1);
    }
    bool verifyPostorder(vector<int>& postorder) {
        return fs(postorder,0,postorder.size()-1);

    }
};

剑指 Offer 17. 打印从1到最大的n位数

class Solution {
public:
    vector<int> printNumbers(int n) {
        vector<int>ans;
        long long limit = 1;
        for(int i=0;i!=n;i++) limit*=10;
        for(int i=1;i<limit;i++)
        {
            ans.push_back(i);
        }
        return ans;


    }
};

剑指 Offer 51. 数组中的逆序对

//归并排序
class Solution {
public:
    int mergeSort(int l, int r, vector<int>& nums, vector<int>& temp)
    {
        if(l>r) return 0;
        if(l==r)
        {
            temp[l]=nums[l];
            return 0;
        }

        int mid = (l+r)/2;
        int i=l,j=mid+1;
        int res = mergeSort(i,mid,nums,temp)+mergeSort(j,r,nums, temp);

        for(int k=l;k<=r;k++)
            temp[k]=nums[k];

        for(int k=l;k<=r;k++)
        {
            if(i>mid)
            {
                nums[k]=temp[j++];
            }
            else if(j>r)
            {
                nums[k]=temp[i++];
            }
            else if(temp[i]<=temp[j])
            {
                nums[k]=temp[i++];
            }
            else if(temp[i]>temp[j])
            {
                nums[k]=temp[j++];
                res+=mid-i+1;
            }
        }

        return res;
    }
    int reversePairs(vector<int>& nums) {
        vector<int> temp(nums.size());
        return mergeSort(0,nums.size()-1,nums,temp);
    }
};

剑指 Offer 45. 把数组排成最小的数

class Solution {
public:

    void Sort(vector<string>&nums, int l, int r)
    {
        if(l>=r) return;
        int i=l,j=r;
        while(i<j)
        {
            while(i<j && nums[j]+nums[l]>=nums[l]+nums[j]) j--;
            while(i<j && nums[i]+nums[l]<=nums[l]+nums[i]) i++;
            swap(nums[i],nums[j]);
        }
        swap(nums[l],nums[i]);
        Sort(nums,l,i-1);
        Sort(nums,i+1,r);
    }

    string minNumber(vector<int>& nums) {
        vector<string> out;
        for(int i=0;i!=nums.size();i++)
            out.push_back(to_string(nums[i]));
        Sort(out,0,out.size()-1);
        string s;
        for(auto p:out)
            s.append(p);
        return s;
    }
};
class Solution {
public:
    string minNumber(vector<int>& nums) {
        vector<string> out;
        for(int i=0;i!=nums.size();i++)
            out.push_back(to_string(nums[i]));
        sort(out.begin(),out.end(),[](string& a,string& b){return a+b<b+a;});
        string s;
        for(int i=0;i!=out.size();i++)
            s.append(out[i]);
        return s;
    }
};

剑指 Offer 61. 扑克牌中的顺子

//排序
class Solution {
public:
    bool isStraight(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int num0=0;
        for(int j=0;j!=nums.size();j++)
        {
            if(nums[j]==0) num0++;
            else if(j>0 && nums[j]==nums[j-1]) return false;
        }
        return nums[4]-nums[num0]<5;
    }
};

剑指 Offer 40. 最小的k个数

class Solution {
public:
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        sort(arr.begin(),arr.end());
        vector<int> ans;
        for(int i=0;i!=k;i++)
        {
            ans.push_back(arr[i]);
        }
        return ans;
    }
};
class Solution {
public:
    void quickSort(vector<int>&arr, int l, int r)
    {
        if(l>=r)return;
        int i=l,j=r;
        while(i<j)
        {
            while(i<j && arr[j]>=arr[l]) j--;
            while(i<j && arr[i]<=arr[l]) i++;
            swap(arr[j],arr[i]);
        }
        swap(arr[l],arr[i]);
        quickSort(arr,l,i-1);
        quickSort(arr,i+1,r);
    }
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        quickSort(arr,0,arr.size()-1);
        vector<int> ans;
        for(int i=0;i!=k;i++)
        {
            ans.push_back(arr[i]);
        }
        return ans;
    }
};

剑指 Offer 41. 数据流中的中位数

//优先队列
class MedianFinder {
public:
    priority_queue<int,vector<int>,less<int>>left;
    priority_queue<int,vector<int>,greater<int>>right;
    /** initialize your data structure here. */
    MedianFinder() {
    }
    
    void addNum(int num) {
        if((left.size()+right.size())%2==0)
        {
            right.push(num);
            left.push(right.top());
            right.pop();
        }
        else{
            left.push(num);
            right.push(left.top());
            left.pop();
        }
    }
    
    double findMedian() {
        if(right.size()==left.size()) return (right.top()+left.top())/2.0;
        else return left.top();

    }
};

剑指 Offer 10- I. 斐波那契数列

class Solution {
public:
    int fib(int n) {
        if(n==0) return 0;
        if(n==1) return 1;
        int p1=0,p2=1;
        for(int i=2;i<=n;i++)
        {
            int temp=(p1+p2)%(1000000007);
            p1=p2;
            p2=temp;
        }
        return p2%(1000000007);
    }
};

剑指 Offer 10- II. 青蛙跳台阶问题

class Solution {
public:
    int numWays(int n) {
        if(n<=1) return 1;
        int p1=1,p2=1;
        for(int i=2;i<=n;i++)
        {
            int temp = (p1+p2)%1000000007;
            p1=p2;
            p2=temp;
        }
        return p2;
    }
};

剑指 Offer 63. 股票的最大利润

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()<=1) return 0;
        int maxValue=prices[prices.size()-1];
        int ans=0;
        for(int i=prices.size()-1;i>=0;i--)
        {
            ans=max(ans,maxValue - prices[i]);
            maxValue=max(maxValue,prices[i]);
        }
        return ans;

    }
};

剑指 Offer 42. 连续子数组的最大和

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

剑指 Offer 47. 礼物的最大价值

class Solution {
public:
    int maxValue(vector<vector<int>>& grid) {
        int is = grid.size(), js = grid[0].size();
        for(int i=1;i!=is;i++)
            grid[i][0]+=grid[i-1][0];
        for(int i=1;i!=js;i++)
            grid[0][i]+=grid[0][i-1];
        for(int i=1;i!=is;i++)
        {
            for(int j=1;j!=js;j++)
            {
                grid[i][j]+=max(grid[i-1][j],grid[i][j-1]);
            }
        }
        return grid[is-1][js-1];

    }
};

剑指 Offer 46. 把数字翻译成字符串

class Solution {
public:
    int translateNum(int num) {
        if(num<10) return 1;
        int p1=1,p2=1;
        string s = to_string(num);
        for(int i=1;i!=s.size();i++)
        {
            if(s[i-1]!='0' && (s[i-1]-'0')*10+(s[i]-'0')<26) 
            {
                int temp=p1+p2;
                p1=p2;
                p2=temp;
            }
            else
            {
                p1=p2;
            }
        }
        return p2;
    }
};

剑指 Offer 48. 最长不含重复字符的子字符串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_set<char> st;
        deque<char> q;
        int ans=0;
        int len=0;
        for(auto c:s)
        {
            if(st.find(c)==st.end())
            {
                st.insert(c);
                q.push_back(c);
                len++;
            }
            else
            {
                while(q.front()!=c)
                {
                    st.erase(q.front());
                    q.pop_front();
                }
                q.pop_front();
                q.push_back(c);
                len=q.size();
            }
            ans=max(ans,len);
        }
        return ans;

    }
};
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char,int> st;
        int ans=0;
        int len=0;
        for(int i=0;i!=s.size();i++)
        {
            auto c=s[i];
            if(st.find(c)==st.end())
            {
                st[c]=i;
                len++;
            }
            else
            {
                len=min(len+1,i-st.at(c));
                st[c]=i;
            }
            ans=max(ans,len);
        }
        return ans;

    }
};

剑指 Offer 49. 丑数

//最有队列
class Solution {
public:
    int nthUglyNumber(int n) {
        priority_queue<long long ,vector<long long >,greater<long long>>q;
        unordered_set<long long>st;
        long long ans=1;
        q.push(2);
        q.push(3);
        q.push(5);
        st.insert(2);st.insert(3);st.insert(5);
        for(int i=2;i<=n;i++)
        {
            ans = q.top();
            q.pop();
            if(st.find(ans*2)==st.end()) {q.push(ans*2);st.insert(ans*2);}
            if(st.find(ans*3)==st.end()) {q.push(ans*3);st.insert(ans*3);}
            if(st.find(ans*5)==st.end()) {q.push(ans*5);st.insert(ans*5);}
        }
        return ans;
    }
};
//动态规划
class Solution {
public:
    int nthUglyNumber(int n) {
        int ans=1;
        int i2=0,i3=0,i5=0;
        vector<int>q;
        q.push_back(1);

        for(int i=1;i!=n;i++)
        {
            int a2=q[i2]*2,a3=q[i3]*3,a5=q[i5]*5;
            int out =min(a2,min(a3,a5));
            q.push_back(out);
            if(out==a2)i2++;
            if(out==a3)i3++;
            if(out==a5)i5++;
        }
        return q[q.size()-1];
    }
};

剑指 Offer 60. n个骰子的点数

class Solution {
public:
    vector<double> dicesProbability(int n) {
        vector<double>ans(6,1.0/6.0);

        for(int i=2;i<=n;i++)
        {
            vector<double>temp(5*i+1,0);
            for(int j=0;j!=ans.size();j++)
            {
                for(int k=0;k!=6;k++)
                {
                    temp[j+k]+=ans[j]/6.0;
                }
            }
            ans=temp;
        }
        return ans;

    }
};

剑指 Offer 19. 正则表达式匹配

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.size() + 1, n = p.size() + 1;
        vector<vector<bool>>t(s.size()+1,vector<bool>(p.size()+1,false));
        t[0][0]=true;
        for(int i=2;i<n;i+=2)
        {
            t[0][i]=t[0][i-2] && p[i-1]=='*';
        }

        for(int i=1;i!=m;i++)
        {
            for(int j=1;j!=n;j++)
            {
                if(p[j-1]=='*')
                {
                    t[i][j]=(t[i][j-2])||(t[i-1][j] && p[j-2]==s[i-1])||(t[i-1][j] && p[j-2]=='.');
                }
                else
                {
                    t[i][j]=(t[i-1][j-1]&&p[j-1]==s[i-1])||(t[i-1][j-1] && p[j-1]=='.');
                }
            }
        }
        return t[m-1][n-1];
    }
};

剑指 Offer 15. 二进制中1的个数

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int ans=0;
        while(n)
        {
            ans+=n&1;
            n=n>>1;
        }
        return ans;
    }
};
class Solution {
public:
    int hammingWeight(uint32_t n) {
        int ans=0;
        while(n)
        {
            ans++;
            n&=n-1;
        }
        return ans;
    }
};

剑指 Offer 65. 不用加减乘除做加法

class Solution {
public:
    int add(int a, int b) {
        while(b)
        {
            int c=(unsigned int)(a&b)<<1;
            a^=b;
            b=c;
        }
        return a;
    }
};

剑指 Offer 56 - I. 数组中数字出现的次数

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        int ans=0;
        for(auto n:nums)
            ans^=n;
        int m=1;
        while(!(ans&m))
            m<<=1;
        int ans1=0,ans2=0;
        for(auto n:nums)
        {
            if(n&m) ans1^=n;
            else ans2^=n;
        }
        return {ans1,ans2};

    }
};

剑指 Offer 56 - II. 数组中数字出现的次数 II

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        vector<int>p(32,0);
        for(int i=0;i!=nums.size();i++)
        {
            for(int j=0;j!=32;j++)
            {
                p[j]+=nums[i]>>j&1;
            }
        }
        int ans=0;
        for(int i=0;i!=32;i++)
        {
            p[i]%=3;
            ans+=p[i]<<i;
        }
        return ans;

    }
};

剑指 Offer 39. 数组中出现次数超过一半的数字

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int count=1;
        int n = nums[0];
        for(int i=1;i!=nums.size();i++)
        {
            if(nums[i]==n) count++;
            else
            {
                count--;
                if(count<0)
                {
                    count=1;
                    n=nums[i];
                }
            }
        }
        return n;

    }
};

剑指 Offer 66. 构建乘积数组

class Solution {
public:
    vector<int> constructArr(vector<int>& a) {
        int l=a.size();
        if(l==0) return {};
        vector<int>left(l);
        left[0]=a[0];
        vector<int>right(l);
        right[l-1]=a[l-1];
        for(int i=1;i!=l;i++)
        {
            left[i]=left[i-1]*a[i];
            right[l-1-i]=right[l-i]*a[l-1-i];
        }
        vector<int>ans(l);
        ans[0]=right[1];
        ans[l-1]=left[l-2];
        for(int i=1;i!=l-1;i++)
        {
            ans[i]=left[i-1]*right[i+1];
        }
        return ans;

    }
};

剑指 Offer 14- I. 剪绳子

class Solution {
public:
    int cuttingRope(int n) {
        if(n<=3) return n-1;
        int p=n/3,q=n%3;
        if(q==0) return pow(3,p);
        if(q==1) return pow(3,p-1)*4;
        return pow(3,p)*2;
    }
};

剑指 Offer 14- II. 剪绳子 II

class Solution {
public:
    int cuttingRope(int n) {
        if(n<=3) return n-1;
        int p=n/3,q=n%3;
        long ans=1;
        for(int i=1;i!=p;i++)
        {
            ans=(3*ans)%1000000007;
        }
        if(q==0)return (3*ans)%1000000007;
        if(q==1)return (4*ans)%1000000007;
        return (6*ans)%1000000007;
    }
};

剑指 Offer 57 - II. 和为s的连续正数序列

class Solution {
public:
    vector<vector<int>> findContinuousSequence(int target) {
        if(target<3) return {};
        vector<vector<int>> ans;
        
        int i=1,j=2,sum=3;
        while(i<j)
        {
            if(sum==target)
            {
                vector<int>temp;
                for(int k=i;k<=j;k++)
                    {
                        temp.push_back(k);
                    }
                ans.push_back(temp);
            }
            if(sum<=target)
            {
                j++;
                sum+=j;
            }
            else
            {
                sum-=i;
                i++;
            }
        }
        return ans;
    }
};

剑指 Offer 62. 圆圈中最后剩下的数字

class Solution {
public:
    int lastRemaining(int n, int m) {
        int ans =0;
        for(int i=2;i<=n;i++)
        {
            ans=(ans+m)%i;
        }
        return ans;
    }
};

剑指 Offer 43. 1~n 整数中 1 出现的次数

class Solution {
public:
    int countDigitOne(int n) {
        int high=n/10;
        int low=0;
        int cur=n%10;
        long p=1;
        int ans=0;
        while(cur!=0 || high!=0)
        {
            if(cur==0)
            {
                ans+=high*p;
            }
            else if(cur==1)
            {
                ans+=high*p+low+1;
            }
            else{
                ans+=(high+1)*p;
            }
            low+=cur*p;
            cur=high%10;
            high/=10;
            p*=10;
        }
        return ans;
    }
};

剑指 Offer 44. 数字序列中某一位的数字

lass Solution {
public:
    int findNthDigit(int n) {
        long  digit=1,start=1,count=9;
        while(n>count)
        {
            n-=count;
            digit++;
            start*=10;
            count=9*digit*start;
        }
        int num = start + (n-1)/digit;
        string numstr = to_string(num);
        int ans = numstr[(n-1)%digit]-'0';
        return ans;
    }
};

1. 两数之和

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

49. 字母异位词分组

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,int>m;
        vector<vector<string>>ans;

        for(int i=0;i!=strs.size();i++)
        {
            string temp=strs[i];
            sort(temp.begin(),temp.end());
            if(m.find(temp)!=m.end())
            {
                ans[m.at(temp)].push_back(strs[i]);
            }
            else
            {
                vector<string>a;
                a.push_back(strs[i]);
                ans.push_back(a);
                m[temp]=ans.size()-1;
            }
        }
        return ans;
    }
};

128. 最长连续序列

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_map<int,int>m;
        sort(nums.begin(),nums.end());
        int ans=0;
        for(int i=0;i!=nums.size();i++)
        {
            if(m.find(nums[i]-1)!=m.end())
                m[nums[i]]=m[nums[i]-1]+1;
            else
                m[nums[i]]=1;
            ans=max(ans,m.at(nums[i]));
        }
        return ans;
    }
};
class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int>m;
        for(auto n:nums) m.insert(n);
        int ans=0;
        for(int i=0;i!=nums.size();i++)
        {
            if(m.find(nums[i]-1)==m.end())
            {
                int len=1;
                while(m.find(nums[i]+len)!=m.end()) len++;
                ans=max(ans,len);
            }
        }
        return ans;
    }
};

283. 移动零

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int j=nums.size()-1;
        int i=0;
        while(i<j)
        {
            while(i<j && nums[i]!=0)i++;
            while(i<j && nums[j]==0)j--;
            for(int k=i;k<j;k++) swap(nums[k],nums[k+1]);
        }
    }
};
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int j=0;
        int i=0;
        while(j<nums.size())
        {
            if(nums[j]!=0)
            {
                swap(nums[i],nums[j]);
                i++;
                j++;
            }
            else
            {
                j++;
            }
        }
    }
};

11. 盛最多水的容器

class Solution {
public:
    int maxArea(vector<int>& height) {
        int i=0,j=height.size()-1;
        int ans=(j-i)*min(height[i],height[j]);
        while(i<j)
        {
            if(height[i]<height[j])
            {
                i++;
                ans=max(ans,(j-i)*(min(height[i],height[j])));
            }
            else
            {
                j--;
                ans=max(ans,(j-i)*(min(height[i],height[j])));
            }
        }
        return ans;
    }
};

15. 三数之和

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>>ans;
        for(int i=0;i!=nums.size();i++)
        {
            if(nums[i]>0) break;
            if(i>0 && nums[i]==nums[i-1]) continue;
            int l=i+1,r=nums.size()-1;
            while(l<r)
            {
                if(nums[l]+nums[r]+nums[i]==0) 
                {
                    ans.push_back({nums[i],nums[l],nums[r]});
                    l++;r--;
                    while(l<r && nums[l]==nums[l-1])l++;
                    while(l<r && nums[r]==nums[r+1])r--;
                }
                else if(nums[l]+nums[r]+nums[i]<0) l++;
                else if(nums[l]+nums[r]+nums[i]>0)r--;
            }
        }
        return ans;
    }
};

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

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char,int>m;
        int ans=0;
        int p=0;
        for(int i=0;i!=s.size();i++)
        {
            if(m.find(s[i])==m.end()) {
                m[s[i]]=i;
                p++;
            }
            else
            {
                p=min(p+1,i-m[s[i]]);
                m[s[i]]=i;
            }
            ans=max(p,ans);

        }
        return ans;
    }
};

438. 找到字符串中所有字母异位词

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        vector<int>pw(26,0);
        vector<int>sw(26,0);
        for(auto c:p)
        {
            pw[c-'a']++;
        }
        vector<int>ans;
        for(int i=0;i!=s.size();i++)
        {
            sw[s[i]-'a']++;
            if(i>=p.size())sw[s[i-p.size()]-'a']--;
            if(i>=p.size()-1)
            {
                if(pw==sw)ans.push_back(i-p.size()+1);
            }
        }
        return ans;

    }
};

560. 和为 K 的子数组

//前缀和
class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        unordered_map<int,int>map;
        map[0]=1;
        int pre=0,count=0;
        for(auto n:nums)
        {
            pre+=n;
            if(map.find(pre-k)!=map.end())
            {
                count+=map[pre-k];
            }
            map[pre]++;
        } 
        return count;
    }
};

239. 滑动窗口最大值

//大顶堆
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        priority_queue<pair<int,int>>p;
        for(int i=0;i!=k;i++)
        {
            while(!p.empty() && p.top().first<=nums[i]) p.pop();
            p.emplace(make_pair(nums[i],i));
        }
        vector<int>ans;
        ans.push_back(p.top().first);
        for(int i=k;i!=nums.size();i++)
        {
            while(!p.empty() && p.top().second<=i-k) p.pop();
            p.emplace(make_pair(nums[i],i));
            ans.push_back(p.top().first);
        }
        return ans;
    }
};
//优先队列
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        deque<int>que;
        vector<int>ans;
        for(int i=0;i!=nums.size();i++)
        {
            
            if(i>=k && nums[i-k]==que.front())
            {
                que.pop_front();
            }
            while(!que.empty() && que.back()<nums[i]) que.pop_back();
            que.push_back(nums[i]);
            if(i>=k-1) ans.push_back(que.front());
        }
        return ans;
    }
};
//前缀后缀
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int>pre(nums.size());
        vector<int>suf(nums.size());

        for(int i=0;i!=nums.size();i++)
        {
            if(i%k==0) pre[i]=nums[i];
            else pre[i]=max(pre[i-1],nums[i]);
        }

        for(int i=nums.size()-1;i>=0;i--)
        {
            if(i==nums.size()-1 || (i+1)%k==0) suf[i]=nums[i];
            else suf[i]=max(suf[i+1],nums[i]);
        }

        vector<int>ans;
        for(int i=0;i<=nums.size()-k;i++)
        {
            ans.push_back(max(suf[i],pre[i+k-1]));
        }
        return ans;
    }
};

76. 最小覆盖子串

class Solution {
public:
    unordered_map<char,int>tt;
    unordered_map<char,int>ss;
    bool check()
    {
        for(auto c:tt)
            if(ss.find(c.first)==ss.end() || c.second>ss.at(c.first)) return false;
        return true;
    }
    string minWindow(string s, string t) {
        for(auto c:t)
        {
            tt[c]++;
        }
        
        int k=0;
        string ans; 
        int count=INT_MAX;
        for(int i=0;i!=s.size();i++)
        {
            ss[s[i]]++;
            bool hit=false;
            while(k<=i && check())
            {
                ss[s[k]]--;
                k++;
                hit=true;
            }
            if(hit && count>i-k+2) 
            {
                count = i-k+2;
                ans=s.substr(k-1,count);
            }

        }
        return ans;

    }
};

53. 最大子数组和

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int pre=0;
        int ans=INT_MIN;
        for(int i=0;i!=nums.size();i++)
        {
            int temp =max(nums[i],pre+nums[i]);
            ans=max(ans,temp);
            pre=temp;
        }
        return ans;
    }
};

56. 合并区间

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(),intervals.end());
        vector<vector<int>>ans;
        int l=intervals[0][0], r=intervals[0][1];
        for(auto t:intervals)
        {
            if(t[0]<=r)
            {
                r=max(r,t[1]);
            }
            else
            {
                ans.push_back({l,r});
                l=t[0];
                r=t[1];
            }

        }
        ans.push_back({l,r});
        return ans;
    }
};

189. 轮转数组

//创建新数组
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        vector<int>ans(nums.size());
        for(int i=0;i!=nums.size();i++)
            ans[(i+k)%nums.size()]=nums[i];
        nums=ans;
    }
};
//反转数组
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        reverse(nums.begin(),nums.end());
        k%=nums.size();
        reverse(nums.begin(),nums.begin()+k);
        reverse(nums.begin()+k,nums.end());
        
    }
};

238. 除自身以外数组的乘积

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int>pre(nums.size(),1);
        vector<int>suf(nums.size(),1);

        for(int i=1;i!=nums.size();i++)
            pre[i]=pre[i-1]*nums[i-1];
        for(int i=nums.size()-2;i>=0;i--)
            suf[i]=suf[i+1]*nums[i+1];
        
        for(int i=0;i!=nums.size();i++)
            nums[i]=(pre[i]*suf[i]);
        return nums;
    }
};

41. 缺失的第一个正数

//原地哈希
class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        for(int i=0;i!=nums.size();i++)
        {
            if(nums[i]<=0) nums[i]=nums.size()+1;
        }

        for(int i=0;i!=nums.size();i++)
        {
            int num=abs(nums[i]);
            if(num<=nums.size()) nums[num-1]=-1*abs(nums[num-1]);
        }

        for(int i=0;i!=nums.size();i++)
        {
            if(nums[i]>0) return i+1;
        }
        return nums.size()+1;
    }
};

73. 矩阵置零

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        bool i0=false,j0=false;

        for(int i=0;i!=matrix.size();i++)
        {
            if(matrix[i][0]==0) 
            {
                j0=true;
                break;
            }
        }

        for(int i=0;i!=matrix[0].size();i++)
        {
            if(matrix[0][i]==0) 
            {
                i0=true;
                break;
            }
        }

        for(int i=1;i!=matrix.size();i++)
        {
            for(int j=1;j!=matrix[0].size();j++)
            {
                if(matrix[i][j]==0)
                {
                    matrix[i][0]=0;
                    matrix[0][j]=0;
                }
            }
        }

        for(int i=1;i!=matrix.size();i++)
        {
            for(int j=1;j!=matrix[0].size();j++)
            {
                if(matrix[i][0]==0 || matrix[0][j]==0)
                {
                    matrix[i][j]=0;
                }
            }
        }
        if(i0)
        {
            for(int i=0;i!=matrix[0].size();i++)
                matrix[0][i]=0;
        }

        if(j0)
        {
            for(int i=0;i!=matrix.size();i++)
                matrix[i][0]=0;
        }

    }
};

54. 螺旋矩阵

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if(matrix.empty())return {};
        int l=0,r=matrix[0].size()-1,u=0,d=matrix.size()-1;

        vector<int>ans;
        while(1)
        {
            for(int i=l;i<=r;i++) ans.push_back(matrix[u][i]);
            if(++u>d) break;
            for(int i=u;i<=d;i++)ans.push_back(matrix[i][r]);
            if(--r<l) break;
            for(int i=r;i>=l;i--)ans.push_back((matrix[d][i]));
            if(--d<u)break;
            for(int i=d;i>=u;i--)ans.push_back(matrix[i][l]);
            if(++l>r)break;
 
        }
        return ans;
    }
};

48. 旋转图像

//反转
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        for(int i=0;i!=matrix.size();i++)
        {
            for(int j=i+1;j!=matrix[0].size();j++)
                swap(matrix[i][j],matrix[j][i]);
        }

        for(auto &c:matrix)
            reverse(c.begin(),c.end());
    }
};

240. 搜索二维矩阵 II

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int l=0,r=matrix[0].size()-1,u=0,d=matrix.size()-1;

            while(u<=d && l<=r)
            {
                if(matrix[u][r]==target) return true;
                else if(matrix[u][r]<target)
                {
                    if(++u>d) return false;
                }
                else
                {
                    if(--r<l) return false;
                }
            }
        return false;
    }
};

160. 相交链表

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(!headA || !headB) return nullptr;
        ListNode* a=headA,*b=headB;
        while(1)
        {
            if(a==b) return a;
            a=a?a->next:headB;
            b=b?b->next:headA;
        }
        return nullptr;

    }
};

206. 反转链表

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head || !head->next) return head;

        auto p = reverseList(head->next);

        head->next->next = head;
        head->next=nullptr;
        return p;
    }
};
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre=nullptr;
        ListNode* now =head;

        while(now)
        {
            auto p = now->next;
            now->next=pre;
            pre=now;
            now=p;
        }
        return pre;
    }
};

234. 回文链表

class Solution {
public:
    bool isPalindrome(ListNode* head) {

        
        ListNode* slow =head;
        ListNode* fast = head;
        while(fast && fast->next)
        {
            fast=fast->next->next;
            slow=slow->next;
        }

        ListNode* pre=nullptr;
        ListNode* now =slow;
        while(now)
        {
            ListNode* next = now->next;
            now->next=pre;
            pre=now;
            now=next;
        }


        while(pre)
        {
            if(pre->val!=head->val) return false;
            pre=pre->next;
            head=head->next;
        }
        return true;
    }
};

141. 环形链表

class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(!head)return false;
        ListNode* fast=head->next;
        ListNode* slow=head;

        while(fast && fast->next)
        {
            if(fast==slow) return true;
            fast=fast->next->next;
            slow=slow->next;
        }
        return false;
    }
};

142. 环形链表 II

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(!head || !head->next) return nullptr;
        ListNode* fast=head->next;
        ListNode* slow =head;

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

        if(fast!=slow) return nullptr;

        ListNode* end=fast;
        fast=fast->next;
        slow=head;
        while(1)
        {
            if(fast==slow)return fast;
            fast=fast==end?head:fast->next;
            slow=slow==end?end->next:slow->next;
        }
        return nullptr;
    }
};

21. 合并两个有序链表

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* head=new ListNode();
        ListNode* p=head;
        while(list1 && list2)
        {
            if(list1->val<list2->val)
            {
                p->next = list1;
                list1=list1->next;
                p=p->next;
            }
            else
            {
                p->next = list2;
                list2=list2->next;
                p=p->next;
            }
        }
        if(list1) p->next=list1;
        if(list2) p->next=list2;
        return head->next;
        
    }
};

2. 两数相加

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

        return head->next;
    }
};

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

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* p=new ListNode();
        p->next=head;
        auto q=p;
        ListNode* fast=head;
        for(int i=0;i!=n;i++) fast=fast->next;
        while(fast)
        {
            q=q->next;
            fast=fast->next;
        }
        q->next=q->next->next;
        return p->next;
    }
};

24. 两两交换链表中的节点

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* h = new ListNode();
        h->next=head;
        ListNode* temp = h;

        while(temp->next && temp->next->next)
        {
            auto p1= temp->next;
            auto p2 = temp->next->next;
            temp->next = p2;
            p1->next=p2->next;
            p2->next=p1;
            temp=p1;
        }
        return h->next;
    }
};
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head || !head->next) return head;

        auto p = head->next;
        head->next=swapPairs(p->next);
        p->next=head;
        return p;
    }
};

25. K 个一组翻转链表

class Solution {
public:
    ListNode* re(ListNode* head, int k, int n)
    {
        if(!head) return head;
        if(n==k) 
        {
            auto p= re(head->next, k,1);
            head->next = (!p)?head->next:p;
            return head;
        }
        else
        {
            auto ans = re(head->next,k,n+1);
            auto p =head->next;
            if(n<k && !ans) return nullptr;

            head->next=p->next;
            p->next=head;
            return ans;
        }
    }
    ListNode* reverseKGroup(ListNode* head, int k) {
         return re(head,k,1);
    }
};

138. 复制带随机指针的链表

class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(!head)return nullptr;
        auto p=head;
        while(p)
        {
            Node* temp = new Node(p->val);
            temp->next=p->next;
            p->next=temp;
            p=temp->next;
        }
        p=head;
        while(p)
        {
            p->next->random = p->random?p->random->next:nullptr;
            p=p->next->next;
        }

        auto ans = head->next;
        auto p1= head;
        auto p2=ans;
        while(p1)
        {
            auto q= p2->next;
            if(q)
            {
                p1->next = q;
                p2->next=q->next;
            }
            else
            {
                p1->next=nullptr;
                p2->next=nullptr;
            }
            p1=p1->next;
            p2=p2->next;

        }

        return ans;
    }
};

148. 排序链表

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(!head || !head->next) return head;
        ListNode* fast = head->next, *slow = head;
        while(fast->next && fast->next->next)
        {
            slow = slow->next;
            fast=fast->next->next;
        }
        auto mid = slow->next;
        slow->next=nullptr;
        auto p1 = sortList(head);
        auto p2 = sortList(mid);

        ListNode* h = new ListNode();
        auto p=h;
        while(p1 && p2)
        {
            if(p1->val<p2->val)
            {
                p->next=p1;
                p1=p1->next;
                p=p->next;
            }
            else
            {
                p->next=p2;
                p2=p2->next;
                p=p->next;
            }

        }
        if(p1)
        {
            p->next=p1;
        }
        if(p2)
        {
            p->next=p2;
        }

        return h->next;
    }
};

23. 合并 K 个升序链表

class Solution {
public:
    ListNode* st(vector<ListNode*>& lists, int i, int j)
    {
        if(i>j) return nullptr;
        if(i==j) return lists[i];
            int mid = (i+j)/2;
            auto p1 = st(lists,i,mid);
            auto p2 = st(lists,mid+1,j);

            ListNode* h = new ListNode();
            auto p =h;
            while(p1 && p2)
            {
                if(p1->val<p2->val)
                {
                    p->next=p1;
                    p1=p1->next;
                    p=p->next;
                }
                else
                {
                    p->next=p2;
                    p2=p2->next;
                    p=p->next;
                }
            }
            if(p1)
            {
                p->next=p1;
            }
            if(p2)
            {
                p->next=p2;
            }
            return h->next;
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return st(lists,0,lists.size()-1);
    }
};

146. LRU 缓存

class Node
{
public:
    Node* left;
    Node* right;
    int key;
    int val;
    Node():key(0),val(0),left(nullptr),right(nullptr){};
    Node(int _key, int _val, Node* _left, Node* _right):key(_key),val(_val),left(_left),right(_right){};
};



class LRUCache {
public:
    int cap;
    int size;
    unordered_map<int,Node*>map;
    Node* begin;
    Node* end;
    LRUCache(int capacity):cap(capacity),size(0) {
        begin = new Node();
        end=new Node();
        begin->right=end;
        end->left=begin;
    }
    
    int get(int key) {
        if(map.find(key)!=map.end())
        {
            auto n = map.at(key);

            n->left->right = n->right;
            n->right->left = n->left;

            auto temp = begin->right;
            begin->right = n;
            n->left=begin;
            n->right=temp;
            temp->left=n;

            return n->val;
        }
        else return -1;
    }
    
    void put(int key, int value) {
        Node* n;
        if(map.find(key)!=map.end()) 
        {
            n = map.at(key);
            n->val=value;

            n->left->right = n->right;
            n->right->left = n->left;

            auto temp = begin->right;
            begin->right = n;
            n->left=begin;
            n->right=temp;
            temp->left=n;
        }
        else 
        {
            n=new Node(key, value, nullptr, nullptr);
            auto temp = begin->right;
            begin->right = n;
            n->left=begin;
            n->right=temp;
            temp->left=n;
            size++;
        }
        map[key]=n;
        
        if(size>cap)
        {
            auto p = end->left;
            end->left=p->left;
            p->left->right=end;
            map.erase(p->key);
            size--;
        }
    }
};

94. 二叉树的中序遍历

class Solution {
public:
    vector<int>ans;
    void t(TreeNode* root)
    {
        if(!root) return;
        t(root->left);
        ans.push_back(root->val);
        t(root->right);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        t(root);
        return ans;
    }
};

104. 二叉树的最大深度

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(!root) return 0;
        return max(maxDepth(root->left),maxDepth(root->right))+1;
    }
};

226. 翻转二叉树

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(!root) return nullptr;

        auto pl = root->left;
        auto pr = root->right;
        root->left = invertTree(pr);
        root->right = invertTree(pl);
        return root;
    }
};

101. 对称二叉树

class Solution {
public:
    bool sy(TreeNode* l, TreeNode* r)
    {
        if(!l && !r) return true;
        else if(!l || !r) return false;
        if(l->val != r->val) return false;
        return sy(l->left,r->right) && sy(l->right,r->left);
    }
    bool isSymmetric(TreeNode* root) {
        return sy(root->left, root->right);
    }
};

543. 二叉树的直径

class Solution {
public:
    int ans=0;
    int d(TreeNode* root) {
        if(!root) return 0;
        if(!root->left && !root->right) return 1;
        int l =d(root->left);
        int r = d(root->right);
        auto len = l + r;
        ans = max(ans, len);
        return max(l,r)+1;
    }

    int diameterOfBinaryTree(TreeNode* root) {
        auto p = d(root);
        return ans;
 
    }
};

102. 二叉树的层序遍历

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(!root) return{};
        deque<TreeNode*>que;
        que.push_back(root);
        vector<vector<int>>ans;
        while(!que.empty())
        {
            vector<int>temp;
            for(auto p:que)
            {
                temp.push_back(p->val);
            }
            ans.push_back(temp);
            int size=que.size();
            for(int i=0;i!=size;i++)
            {
                if(que.front()->left) que.push_back(que.front()->left);
                if(que.front()->right) que.push_back(que.front()->right);
                que.pop_front();
            }
        }
        return ans;
    }
};

108. 将有序数组转换为二叉搜索树

class Solution {
public:
    TreeNode* sort(vector<int>& nums, int l, int r)
    {
        if(l>r) return nullptr;
        int mid = (l+r)/2;
        TreeNode* root = new TreeNode(nums[mid]);
        root->left = sort(nums,l,mid-1);
        root->right = sort(nums,mid+1,r);
        return root;

    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return sort(nums,0,nums.size()-1);
        
    }
};

98. 验证二叉搜索树

class Solution {
public:
    long p = LONG_MIN;
    bool isValidBST(TreeNode* root) {
        if(!root) return true;
        bool l =isValidBST(root->left);
        if(p>=root->val) return false;
        p=root->val;
        bool r = isValidBST(root->right);
        return l&&r;
    }
};

230. 二叉搜索树中第K小的元素

class Solution {
public:
    int count=0;
    int kthSmallest(TreeNode* root, int k) {
        if(!root) return 0;
        int left = kthSmallest(root->left,k);
        count++;
        if(count>k) return left;
        if(count==k) return root->val; 
        return kthSmallest(root->right,k);
    }
};

199. 二叉树的右视图

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        if(!root)return {};
        deque<TreeNode*>que;
        que.push_back(root);
        vector<int> ans;

        while(!que.empty())
        {
            ans.push_back(que.front()->val);
            int size = que.size();
            for(int i=0;i!=size;++i)
            {
                if(que.front()->right)que.push_back(que.front()->right);
                if(que.front()->left)que.push_back(que.front()->left);
                que.pop_front();
            }
        }
        return ans;
    }
};

114. 二叉树展开为链表

class Solution {
public:
    pair<TreeNode*,TreeNode*> ft(TreeNode*root)
    {
        if(!root) return make_pair(nullptr,nullptr);
        if(!root->left && ! root->right) return make_pair(root,root);
        auto pl=root->left;
        auto pr = root->right;
        root->left=nullptr;
        auto rl=ft(pl);
        auto rr=ft(pr);
        if(rl.first && rr.first)
        {
            root->right=rl.first;
            rl.second->right=rr.first;
            return make_pair(root,rr.second);
        }
        else if(rr.first)
        {
            root->right = rr.first;
            return make_pair(root,rr.second);
        }
        else if(rl.first)
        {
            root->right=rl.first;
            return make_pair(root,rl.second);
        }
        return make_pair(root,root);
    }
    void flatten(TreeNode* root) {
        auto p = ft(root);
    }
};

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

class Solution {
public:
    TreeNode* tr(vector<int>& preorder, vector<int>& inorder,int pl,int pr, int il, int ir)
    {
        if(pl>pr) return nullptr;
        TreeNode* root = new TreeNode(preorder[pl]);

        int mid;
        for(int i=il;i<=ir;i++)
        {
            if(inorder[i]==root->val) 
            {
                mid=i;break;
            }
        }

        root->left = tr(preorder,inorder,pl+1,pl+(mid-il),il,mid-1);
        root->right=tr(preorder,inorder,pl+(mid-il)+1,pr,mid+1,ir);
        return root;

    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return tr(preorder,inorder,0,preorder.size()-1,0,inorder.size()-1);    
    }
};

437. 路径总和 III

class Solution {
public:
    unordered_map<long long,int>map;
    int ans=0;
    void path(TreeNode* r, int targetSum, long long pre)
    {
        if(!r)return;
        long long sum = r->val+pre;
        if(map.find(sum-targetSum)!=map.end()) ans+=map.at(sum-targetSum);
        map[sum]++;
        path(r->left, targetSum, sum);
        path(r->right, targetSum, sum);
        map[sum]--;
    }
    int pathSum(TreeNode* root, int targetSum) {
        map[0]=1;
        path(root,targetSum,0);
        return ans;
    }
};

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

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

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

class Solution {
public:
    int ans=INT_MIN;

    int m(TreeNode* root) {
        if(!root) return 0;
        int l = m(root->left);
        int r = m(root->right);
        int temp = max(l+r+root->val,max(max(root->val+l,root->val+r),root->val));
        ans=max(ans,temp);

        int sub = max(root->val,max(root->val+l,root->val+r));
        return sub;
    }

    int maxPathSum(TreeNode* root) {
        auto p =m(root);
        return ans;
    }
};

200. 岛屿数量

class Solution {
public:
    void num(vector<vector<char>>& g, int i, int j)
    {
        if(i<0 || i>g.size()-1 || j<0 || j>g[0].size()-1) return;

        if(g[i][j]=='0') return;
        g[i][j]='0';
        num(g,i-1,j);
        num(g,i+1,j);
        num(g,i,j-1);
        num(g,i,j+1);
    }
    int numIslands(vector<vector<char>>& grid) {
        int ans=0;
        for(int i=0;i!=grid.size();i++)
        {
            for(int j=0;j!=grid[0].size();j++)
            {
                if(grid[i][j]=='1')
                {
                    ans++;
                    num(grid,i,j);
                }
            }
        }
        return ans;
    }

};

994. 腐烂的橘子

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) {
        deque<pair<int,int>>que;
        int f=0;
        for(int i=0;i!=grid.size();++i)
        {
            for(int j=0;j!=grid[0].size();++j)
            {
                if(grid[i][j]==2) 
                    {
                        que.push_back(make_pair(i,j));
                    }
                else if(grid[i][j]==1) f++;
            }
        }
        vector<vector<int>> t={{-1,0},{1,0},{0,-1},{0,1}};

        int ans=0;
        while(!que.empty() && f>0)
        {
            int size = que.size();
            for(int i=0;i!=size;i++)
            {
                auto p = que.front();
                que.pop_front();
                for(auto det:t)
                {
                    int x= p.first+det[0];
                    int y=p.second+det[1];
                    if(x<0||y<0||x>grid.size()-1||y>grid[0].size()-1||grid[x][y]!=1) continue;
                    grid[x][y]=2;
                    f--;
                    que.push_back(make_pair(x,y));
                }
            }
            ans++;
            
        }
        if(f!=0) return -1;
        return ans;
        
    }
};

207. 课程表

//拓扑排序
class Solution {
public:
    
    bool can(int course, vector<vector<int>>&map, vector<int>&cs)
    {
        if(map[course].empty())
        {
            cs[course]=2;
            return true;
        }
        cs[course]=1;
        auto k = map[course];
        bool ans=true;
        for(auto p:k)
        {
            if(cs[p]==1) return false;
        }
        for(auto p:k)
        {
            if(cs[p]==0)
                ans = ans && can(p,map, cs);
        }
        if(ans) cs[course]=2;
        return ans;
    }
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        vector<vector<int>>map(numCourses);
        for(auto t:prerequisites)
        {
            map[t[0]].push_back(t[1]);
        }

        vector<int>ans(numCourses,0);
        for(int i=0;i!=numCourses;i++){
            if(ans[i]==0 && !can(i,map, ans)) return false;
        }
        return true;

    }
};
//入度排序
class Solution {
public:
    vector<int>in;
    vector<vector<int>>edge;
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        in.resize(numCourses);
        edge.resize(numCourses);
        for(auto t:prerequisites)
        {
            edge[t[1]].push_back(t[0]);
            in[t[0]]++;
        }

        deque<int>que;
        for(int i=0;i!=in.size();i++)
        {
            if(in[i]==0) que.push_back(i);
        }

        int ans=0;
        while(!que.empty())
        {
            ans++;
            auto p =que.front();
            que.pop_front();

            for(auto t:edge[p])
            {
                if(in[t]!=0)
                {
                    --in[t];
                    if(in[t]==0) que.push_back(t);
                }
            }
        }
        return ans==numCourses;

    }
};

208. 实现 Trie (前缀树)

class Trie {
public:
    vector<Trie*>children;
    bool isend;
    Trie():children(26),isend(false) {
    }
    
    

    void insert(string word) {
        auto node = this;
        for(auto c:word)
        {
            if(!node->children[c-'a']) node->children[c-'a']=new Trie();
            node = node->children[c-'a'];
        }
        node->isend=true;
    }
    
    Trie* s(string word)
    {
        auto node = this;
        for(auto c:word)
        {
            if(!node->children[c-'a']) 
            {
                return nullptr;
            }
            else
            {
                node = node->children[c-'a'];
            }
        }
        return node;
    }

    bool search(string word) {
        auto n = s(word);
        return n && n->isend;
    }
    
    bool startsWith(string prefix) {
        auto n =s(prefix);
        return n;
    }
};

46. 全排列

class Solution {
public:
    vector<vector<int>>ans;
    void per(vector<int>&nums, int id)
    {
        if(id==nums.size()-1)
        {
            ans.push_back(nums);
            return;
        }
        for(int i=id;i!=nums.size();i++)
        {
            swap(nums[id],nums[i]);
            per(nums,id+1);
            swap(nums[id],nums[i]);
        }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        per(nums,0);
        return ans;
    }
};

78. 子集

class Solution {
public:
    vector<vector<int>>ans;
    vector<int>temp;
    void sub(vector<int>&nums, int id)
    {
        if(id==nums.size())
        {
            ans.push_back(temp);
            return;
        }

        temp.push_back(nums[id]);
        sub(nums,id+1);
        temp.pop_back();
        sub(nums,id+1);
    }
    vector<vector<int>> subsets(vector<int>& nums) {
        sub(nums,0);
        return ans;
    }
};

17. 电话号码的字母组合

class Solution {
public:
    unordered_map<char,string>map;
    vector<string>ans;
    string temp;
    void lc(string digits, int id)
    {
        if(id==digits.size()) 
        {
            ans.push_back(temp);return;
        }

        string f = map.at(digits[id]);
        for(auto c:f)
        {
            temp.push_back(c);
            lc(digits,id+1);
            temp.pop_back();
        }
    }
    vector<string> letterCombinations(string digits) {
        if(digits.empty()) return {};
        map['2']="abc";
        map['3']="def";
        map['4']="ghi";
        map['5']="jkl";
        map['6']="mno";
        map['7']="pqrs";
        map['8']="tuv";
        map['9']="wxyz";

        lc(digits,0);
        return ans;

    }
};

39. 组合总和

class Solution {
public:
    vector<vector<int>>ans;
    vector<int>temp;

    void f(vector<int>& candidates, int target, int id, int sum)
    {
        if(sum==target)
        {
            ans.push_back(temp);return;
        }
        if(sum>target) return;

        for(int i =id;i!=candidates.size();i++)
        {
            temp.push_back(candidates[i]);
            f(candidates,target,i,sum+candidates[i]);
            temp.pop_back();
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        f(candidates,target,0,0);
        return ans;
    }
};

22. 括号生成

class Solution {
public:
    vector<string>ans;
    string temp;
    int left;
    int right;
    void ge()
    {
        if(left==0 && right==0)
        {
            ans.push_back(temp);
            return;
        }

        if(left>0)
        {
            --left;
            temp.push_back('(');
            ge();
            temp.pop_back();
            ++left;
        }
        if(left<right)
        {
            --right;
            temp.push_back(')');
            ge();
            temp.pop_back();
            ++right;
        }
    }
    vector<string> generateParenthesis(int n) {
        left=n;right=n;
        ge();
        return ans;
    }
};

79. 单词搜索

class Solution {
public:
    bool ex(vector<vector<char>>& board, string word, int id, int i, int j)
    {
        if(i<0 || j<0 || i>board.size()-1 || j>board[0].size()-1 || board[i][j]=='0'||board[i][j]!=word[id]) return false;
        if(id==word.size()-1) return true;
        board[i][j]='0';
        bool ans=ex(board,word,id+1,i-1,j)||ex(board,word,id+1,i+1,j)||ex(board,word,id+1,i,j-1)||ex(board,word,id+1,i,j+1);

        board[i][j]=word[id];
        return ans;
    }
    bool exist(vector<vector<char>>& board, string word) {
        bool ans=false;
        for(int i=0;i!=board.size();i++)
        {
            for(int j=0;j!=board[0].size();j++)
            {
                if(board[i][j]==word[0] && ex(board,word,0,i,j)) return true;
            }
        }
        return false;
    }
};

131. 分割回文串

class Solution {
public:
    vector<vector<string>>ans;
    vector<string>temp;
    vector<vector<bool>>dp;

    void dfs(string s, int id)
    {
        if(id==s.size()) 
        {
            ans.push_back(temp);return;
        }


        for(int i=id;i!=s.size();i++)
        {
            if(dp[id][i]) 
            {
                temp.push_back(s.substr(id,i-id+1));
                dfs(s,i+1);
                temp.pop_back();
            }
        }

    }
    vector<vector<string>> partition(string s) {
        dp.assign(s.size(),vector<bool>(s.size(),true));

        for(int i=s.size()-1;i>=0;--i)
        {
            for(int j=i+1;j!=s.size();j++)
            {
                dp[i][j]=s[i]==s[j]&&dp[i+1][j-1];
            }
        }

        dfs(s,0);
        return ans;
    }
};

51. N 皇后

class Solution {
public:
    vector<vector<string>>ans;
    vector<string>temp;
    unordered_set<int>c,xpy,xmy;
    void so(int n, int id)
    {
        if(id==n)
        {
            ans.push_back(temp);return;
        }
        for(int i=0;i!=n;i++)
        {
            if(c.find(i)==c.end() && xpy.find(i+id)==xpy.end() && xmy.find(id-i)==xmy.end())
            {
                c.insert(i);xpy.insert(i+id);xmy.insert(id-i);
                temp[id][i]='Q';
                so(n,id+1);
                temp[id][i]='.';
                c.erase(i);xpy.erase(i+id);xmy.erase(id-i);
            }
        }
    }

    vector<vector<string>> solveNQueens(int n) {
        temp.assign(n,string(n,'.'));
        so(n,0);
        return ans;
    }
};

35. 搜索插入位置

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int l=0,r=nums.size()-1;
        
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(nums[mid]==target) return mid;
            else if(nums[mid]<target) l=mid+1;
            else r=mid-1;
        }
        return l;

    }
};

74. 搜索二维矩阵

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

    }
};

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

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int i=0,j=nums.size()-1;
        int left;
        while(i<=j)
        {
            left=(i+j)/2;
            if(nums[left]>=target) j=left-1;
            else i=left+1;
        }

        int a=0,b=nums.size()-1;
        int right;
        while(a<=b)
        {
            right=(a+b)/2;
            if(nums[right]<=target) a=right+1;
            else b=right-1;
        }
        if(a-j==1) return {-1,-1};
        else return {j+1,a-1};
    }
};

33. 搜索旋转排序数组

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

153. 寻找旋转排序数组中的最小值

class Solution {
public:
    int findMin(vector<int>& nums) {
        int i=0,j=nums.size()-1;
        int mid;
        while(i<=j)
        {
            mid=(i+j)/2;
            if(nums[mid]<nums[(mid-1+nums.size())%nums.size()]) break;
            else if(nums[mid]>nums[nums.size()-1]) i=mid+1;
            else j=mid-1;
        }
        return nums[mid];
    }
};

20. 有效的括号

//栈
class Solution {
public:
    bool isValid(string s) {
        deque<char> que;
        for(auto c:s)
        {
            if(que.empty()) que.push_back(c);
            else if(c==')' && que.back()=='(' || c==']' && que.back()=='[' || c=='}' && que.back()=='{')
            {
                que.pop_back();
            }
            else{
                que.push_back(c);
            }
        }
        return que.empty();
    }
};

155. 最小栈

//辅助栈
class MinStack {
public:
    deque<int>q;
    deque<int>min_q;
    MinStack() {
        min_q.push_back(INT_MAX);
    }
    
    void push(int val) {
        q.push_back(val);
        min_q.push_back(min(val,min_q.back()));
    }
    
    void pop() {
        q.pop_back(); 
        min_q.pop_back();   
        }
    
    int top() {
        return q.back();
    }
    
    int getMin() {
        return min_q.back();
    }
};

394. 字符串解码

class Solution {
public:
    string decodeString(string s) {
        string stack="";
        for(auto c:s)
        {
            if(c==']')
            {
                string temp;
                while(stack.back()!='[')
                {
                    temp.push_back(stack.back());
                    stack.pop_back();
                }
                reverse(temp.begin(),temp.end());
                stack.pop_back();

                string num;
                while(!stack.empty() && stack.back()>='0' && stack.back()<='9')
                {
                    num.push_back(stack.back());
                    stack.pop_back();
                }
                reverse(num.begin(),num.end());
                
                int n = stoi(num);
                for(int i=0;i!=n;i++)
                {
                    stack=stack+temp;
                }
            }
            else
            {
                stack.push_back(c);
                
            }
        }
        return stack;
    }
};

739. 每日温度

//单调栈
class Solution {
public:
    vector<int> dailyTemperatures(vector<int>& temperatures) {
        vector<int>ans=vector<int>(temperatures.size(),0);
        vector<int>stack;
        for(int i=0;i!=temperatures.size();++i)
        {
            if(stack.empty()) stack.push_back(i);
            else
            {
                while(!stack.empty() && temperatures[stack.back()]<temperatures[i])
                {
                    ans[stack.back()]=i-stack.back();
                    stack.pop_back();
                }
                stack.push_back(i);
            }
        }
        return ans;
    }
};

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

//堆
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int,vector<int>,less<int>>que;
        for(auto n:nums)
        {
            que.push(n);
        }
        for(int i=0;i!=k-1;i++)
        {
            que.pop();
        }
        return que.top();
    }
};

347. 前 K 个高频元素

//堆
    bool comp(pair<int,int>x,pair<int,int>y)
    {
        return x.second<y.second;
    }

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int,int>map;
        for(auto n:nums)
        {
            ++map[n];
        }
        priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(&comp)>que(comp);
        for(auto n:map)
        {
            que.push(n);
        }
        vector<int>ans;
        for(int i=0;i!=k;++i)
        {
            ans.push_back(que.top().first);
            que.pop();
        }
        return ans;
    }
};

121. 买卖股票的最佳时机

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int minV=prices[0];
        int ans=INT_MIN;
        for(auto p:prices)
        {
            int temp = p-minV;
            minV=min(p,minV);
            ans=max(ans,temp);
        }
        return ans;
    }
};

55. 跳跃游戏

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int ans=0;
        for(int i=0;i!=nums.size();++i)
        {
            if(i>ans)return false;
            ans = max(ans,i+nums[i]);
        }
        return true;
    }
};

45. 跳跃游戏 II

class Solution {
public:
    int jump(vector<int>& nums) {
        int maxpos=0;
        int ans=0;
        int end=0;
        for(int i=0;i!=nums.size()-1;++i)
        {
            maxpos=max(maxpos,nums[i]+i);
            if(i==end)
            {
                ans++;
                end=maxpos;
            }
        }
        return ans;
    }
};

763. 划分字母区间

class Solution {
public:
    vector<int> partitionLabels(string s) {
        vector<int>f(26);
        for(int i=0;i!=s.size();++i)
        {
            f[s[i]-'a']=i;
        }
        int pre=0;int last;
        vector<int>ans;
        while(pre<s.size())
        {
            int temp=0;
            last = f[s[pre]-'a'];
            while(pre<last)
            {
                last=max(f[s[pre]-'a'],last);
                ++pre;
                ++temp;
            }
            ++pre;
            ans.push_back(temp+1);
        }
        return ans;
    }
};

70. 爬楼梯

class Solution {
public:
    int climbStairs(int n) {
        int p0=1;
        int p1=1;
        for(int i=2;i<=n;i++)
        {
            int temp=p0+p1;
            p0=p1;
            p1=temp;
        }
        return p1;
    }
};

118. 杨辉三角

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>>ans;
        for(int i=0;i!=numRows;++i)
        {
            ans.push_back(vector<int>(i+1,1));
            for(int j=0;j<i-1;++j)
            {
                ans.back()[j+1]=ans[ans.size()-2][j]+ans[ans.size()-2][j+1];
            }
        }
        return ans;
    }
};

198. 打家劫舍

class Solution {
public:
    int rob(vector<int>& nums) {
        int p0 = 0, p1 = 0;
        for(auto n:nums)
        {
            int temp = max(p0+n,p1);
            p0=p1;
            p1=temp;
        }
        return p1;
    }
};

279. 完全平方数

class Solution {
public:
    int numSquares(int n) {
        vector<int>t(n+1);
        t[0]=0;
        for(int i=1;i<=n;++i)
        {
            int p=sqrt(i);
            int temp=INT_MAX;
            for(int j=1;j<=p;++j)
            {
                temp=min(temp,t[i-j*j]+1);
            }
            t[i]=temp;
        }
        return t.back();
    }
};

322. 零钱兑换

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<long long>ans(amount+1,INT_MAX);
        ans[0]=0;
        sort(coins.begin(),coins.end());
        for(long long i=0;i<=amount;++i)
        {
            if(ans[i]==INT_MAX) continue;
            for(long long j=0;j!=coins.size();++j) 
            {
                if(i+coins[j]>amount) break;
                ans[i+coins[j]]=min(ans[i+coins[j]],ans[i]+1);
            }
        }
        return ans.back()==INT_MAX?-1:ans.back();
    }
};

139. 单词拆分

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        vector<bool>ans(s.size()+1,false);
        ans[0]=true;

        for(int i=0;i!=ans.size();++i)
        {
            if(ans[i])
            {
                for(auto c:wordDict)
                {
                    int l=c.size();
                    if(i+l<=ans.size()-1 &&  s.substr(i,l)==c) ans[i+l]=true;
                }
            }
        }
        return ans.back();
    }
};

300. 最长递增子序列

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int>ans(nums.size(),1);
        int a=1;
        for(int i=1;i!=nums.size();++i)
        {
            int temp=1;
            for(int j=0;j!=i;++j)
            {
                if(nums[j]<nums[i])
                {
                    temp = max(temp,ans[j]+1);
                }
            }
            ans[i]=temp;
            a=max(a,ans[i]);
        }
        return a;

    }
};
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int>ans;
        for(auto n:nums)
        {
            if(ans.empty()) ans.push_back(n);
            else if(ans.back()<n) ans.push_back(n);
            else
            {
                int l=0;int r=ans.size()-1;
                while(l<=r)
                {
                    int mid=(l+r)/2;
                    if(ans[mid]<n) l=mid+1;
                    else r=mid-1;
                }
                ans[l]=n;
            }
        }
        return ans.size();

    }
};

152. 乘积最大子数组

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int pre0=nums[0],pre1=nums[0];
        int ans=nums[0];
        for(int i=1;i!=nums.size();++i)
        {
            int n=nums[i];
            int t0 = min(n,min(pre0*n,pre1*n));
            int t1 = max(n,max(pre0*n,pre1*n));
            ans = max(ans,t1);
            pre0 = t0;
            pre1 = t1;
        }
        return ans;
    }
};

416. 分割等和子集

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum=0;
        for(auto n:nums) sum+=n;
        if(sum%2==1) return false;

        sum/=2;

        vector<bool>ans(sum+1,false);
        ans[0]=true;
        for(int i=0;i!=nums.size();i++)
        {
            for(int j=ans.size()-1;j>0;--j)
            {
                ans[j]=ans[j] || nums[i]==j || nums[i]<j && ans[j-nums[i]];
            }
        }
        return ans.back();
    }
};

62. 不同路径

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<int>ans(n,1);
        for(int i=1;i!=m;++i)
        {
            for(int j=1;j!=n;++j)
            {
                ans[j]=ans[j]+ans[j-1];
            }
        }
        return ans.back();
    }
};

64. 最小路径和

lass Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        for(int i=1;i!=grid.size();++i)grid[i][0]+=grid[i-1][0];
        for(int i=1;i!=grid[0].size();++i)grid[0][i]+=grid[0][i-1];

        for(int i=1;i!=grid.size();++i)
        {
            for(int j=1;j!=grid[0].size();++j)
            {
                grid[i][j]+=min(grid[i-1][j],grid[i][j-1]);
            }
        }
        return grid.back().back();
    }
};

5. 最长回文子串

class Solution {
public:
    string longestPalindrome(string s) {
        vector<vector<bool>>ans(s.size(),vector<bool>(s.size(),true));
        int num=INT_MIN;
        string out=s.substr(s.size()-1,1);
        for(int i=ans.size()-1;i>=0;--i)
        {
            for(int j=i+1;j!=s.size();++j)
            {
                ans[i][j]=s[i]==s[j] && ans[i+1][j-1];
                if(ans[i][j] && num<j-i+1) 
                {
                    num=j-i+1;
                    out = s.substr(i,num);
                }
            }
        }
        return out;
    }
};

1143. 最长公共子序列

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        vector<vector<int>>ans(text1.size()+1,vector<int>(text2.size()+1));
        ans[0][0]=0;
        for(int i=1;i!=ans.size();++i) ans[i][0]=0;
        for(int i=1;i!=ans[0].size();++i) ans[0][i]=0;

        for(int i=1;i!=ans.size();++i)
        {
            for(int j=1;j!=ans[0].size();++j)
            {
                if(text1[i-1]==text2[j-1]) ans[i][j]=ans[i-1][j-1]+1;
                else
                {
                    ans[i][j]=max(ans[i-1][j],ans[i][j-1]);
                }
            }
        }
        return ans.back().back();
    }
};

136. 只出现一次的数字

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ans=0;
        for(auto n:nums) ans^=n;
        return ans;
    }
};

169. 多数元素

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int count=0;
        int ans;
        for(auto n:nums)
        {
            if(count==0)
            {
                count=1;
                ans=n;
            }
            else if(n==ans)
            {
                count++;
            }
            else
            {
                count--;
            }
        }
        return ans;
    }
};

75. 颜色分类

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int i=0;int j=nums.size()-1;
        while(i<=j)
        {
            while(i<nums.size() && nums[i]==0)++i;
            while(j>=0 && nums[j]!=0)--j;
            if(i>j)break;
            swap(nums[i],nums[j]);
        }

        j=nums.size()-1;
        while(i<=j)
        {
            while(i<nums.size() && nums[i]==1)++i;
            while(j>=0 && nums[j]!=1)--j;
            if(i>j)break;
            swap(nums[i],nums[j]);
        }
    }
};

31. 下一个排列

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        for(int i=nums.size()-2;i>=0;--i)
        {
            if(nums[i]>=nums[i+1]) continue;
            int a=i+1,b=nums.size()-1;
            while(a<=b)
            {
                int mid=(a+b)/2;
                if(nums[mid]<=nums[i])b=mid-1;
                else a=mid+1;
            }
            swap(nums[i],nums[b]);
            sort(nums.begin()+i+1,nums.end());
            return;
        }
        sort(nums.begin(),nums.end());
    }
};

287. 寻找重复数

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        for(int i=0;i!=nums.size();++i)
        {
            if(nums[i]==i+1) continue;
            
            while(nums[i]!=i+1) 
            {
                if(nums[nums[i]-1]==nums[i]) return nums[i];
                swap(nums[i],nums[nums[i]-1]);
            }

        }
        return nums.back();
    }
};
posted @ 2023-07-07 00:42  ETHERovo  阅读(24)  评论(0编辑  收藏  举报