天天看點

Leedcode高頻題刷刷刷ing

給定一個整數數組 A,坡是元組 (i, j),其中 i < j 且 A[i] <= A[j]。這樣的坡的寬度為 j - i。

找出 A 中的坡的最大寬度,如果不存在,傳回 0 。

雙關鍵字排序

用單調棧維護下标和ans這兩個值

建立一個p的單調棧,值+下标雙關鍵字排序

如果值相等就按照下标降序

如果值不相等就按照再nums數組裡的大小順序排序

因為當j如果定下來的話,那麼nums上小于nums【p[j]】的在

p數組上位于左邊,也就是說j确定了的話,答案i隻能在j的左邊找

然後求答案的時候從左到右周遊,

class Solution {
public:
    int maxWidthRamp(vector<int>& nums) {
        vector<int>p(nums.size());
        for(int i=0;i<nums.size();i++)p[i]=i;
        sort(p.begin(),p.end(),[&](int a,int b){
            if(nums[a]!=nums[b])return nums[a]<nums[b];
            else return a<b;
        });
        int ans=0;
        for(int j=0,i=p[0];j<nums.size();j++){
            ans=max(ans , p[j]-i);
            i=min(i,p[j]);
        }
        return ans;
    }
};
           
class Solution {
public:
    double get_dist(double x1,double y1,double x2,double y2){
        return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    }
    double minAreaFreeRect(vector<vector<int>>& points) {
        vector<vector<double>>q;
        for(int i=0;i<points.size();i++){
            for(int j=0;j<i;j++){

                double cx=(points[i][0]+points[j][0]);
                double cy=(points[i][1]+points[j][1]);
                double d=get_dist(points[i][0],points[i][1],points[j][0],points[j][1]);
                q.push_back({cx,cy,d,double(i),double(j)});
            }
        }
        sort(q.begin(),q.end());
        double ans=1e15;
        for(int i=0;i<q.size();i++){
            int j=i+1;
            while(j<q.size()&&q[i][0]==q[j][0]&&q[i][1]==q[j][1]&&q[i][2]==q[j][2])j++;
            //i到j-1這段區間都是中點相等,對角線相等的一對點
            //現在要兩兩取值求答案
            for(int a=i;a<j;a++){
                double x1=points[q[a][3]][0];
                double y1=points[q[a][3]][1];
                for(int b=i;b<a;b++){
                    double x2=points[q[b][3]][0];
                    double y2=points[q[b][3]][1];
                    double x3=points[q[b][4]][0];
                    double y3=points[q[b][4]][1];
                    double t=get_dist(x1,y1,x2,y2)*get_dist(x1,y1,x3,y3);
                    ans=min(ans,t);
                }
            }
            i=j-1;
        }
        if(ans==1e15)ans=0;
        return ans;
    }
};
           

給定一個清單 accounts,每個元素 accounts[i] 是一個字元串清單,其中第一個元素 accounts[i][0] 是 名稱 (name),其餘元素是 emails 表示該賬戶的郵箱位址。

現在,我們想合并這些賬戶。如果兩個賬戶都有一些共同的郵箱位址,則兩個賬戶必定屬于同一個人。請注意,即使兩個賬戶具有相同的名稱,它們也可能屬于不同的人,因為人們可能具有相同的名稱。一個人最初可以擁有任意數量的賬戶,但其所有賬戶都具有相同的名稱。

合并賬戶後,按以下格式傳回賬戶:每個賬戶的第一個元素是名稱,其餘元素是 按字元 ASCII 順序排列 的郵箱位址。賬戶本身可以以 任意順序 傳回。

來源:力扣(LeetCode)

連結:https://leetcode-cn.com/problems/accounts-merge

著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。

class Solution {
public:
    vector<int>p;
    int find(int x){
        if(p[x]==x)return x;
        return p[x]=find(p[x]);
    }
    vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) {
        int n=accounts.size();
        for(int i=0;i<n;i++)p.push_back(i);
        unordered_map<string,vector<int>>hash;
        for(int i=0;i<n;i++){
            for(int j=1;j<accounts[i].size();j++){
                hash[accounts[i][j]].push_back(i);
            }
        }
        
        for(auto& [k,v] : hash){
            for(int i=1;i<v.size();i++){
                p[find(v[i])]=p[find(v[0])];
            }
        }

        vector<set<string>>res(n);
        for(int i=0;i<n;i++){
            for(int j=1;j<accounts[i].size();j++){
                res[find(i)].insert(accounts[i][j]);
            }
        }
        vector<vector<string>>ans;
        for(int i=0;i<n;i++){
            if(res[i].size()){
                vector<string>t;
                t.push_back(accounts[i][0]);
                for(auto s:res[i])t.push_back(s);
                ans.push_back(t);
            }
        }
        return ans;
    }
};
           

給定一棵二叉樹,你需要計算它的直徑長度。一棵二叉樹的直徑長度是任意兩個結點路徑長度中的最大值。這條路徑可能穿過也可能不穿過根結點。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int ans=0;
    int dfs(TreeNode* root){
        if(!root)return 0;
        int L=dfs(root->left);
        int R=dfs(root->right);
        ans=max(ans,L+R);
        return max(L,R)+1;
    }
    int diameterOfBinaryTree(TreeNode* root) {
        dfs(root);
        return ans;
    }
};
           
![在這裡插入圖檔描述](https://img-blog.csdnimg.cn/be53a52a76a14e3b9e75d797156edd8c.png)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(!root)return 0;
        swap(root->left , root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};
           
Leedcode高頻題刷刷刷ing
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(!root)return true;
        return dfs(root->left,root->right);
        //解決這道題需要兩個參數
    }
    bool dfs(TreeNode* p,TreeNode* q){
        if(!p&&!q)return 1;//左右兩邊都是空的
        else if(!p||!q||p->val!=q->val)return 0;
        //一邊是空的另一邊非空或者val不相等傳回false
        return dfs(p->left,q->right) & dfs(q->left, p->right);
        //左子樹的左等于右子樹的右
        //右子樹的左等于左子樹的右
        //取&符号
        //很簡單,但是很精妙,要好好揣摩消化吸收
    }
};
           
Leedcode高頻題刷刷刷ing
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool flipEquiv(TreeNode* root1, TreeNode* root2) {
        if(!root1&&!root2)return 1;
        else if(!root1||!root2||root1->val!=root2->val)return 0;
        return flipEquiv(root1->left, root2->left)&&flipEquiv(root1->right, root2->right) || flipEquiv(root1->left, root2->right)&&flipEquiv(root1->right, root2->left);

    }
};
           
Leedcode高頻題刷刷刷ing
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int ans=-0x3f3f3f3f;
    int maxPathSum(TreeNode* root) {
        dfs(root);
        return ans;
    }
    int dfs(TreeNode* u){
        if(!u)return 0;
        int l=max(0,dfs(u->left));
        int r=max(0,dfs(u->right));
        ans=max(ans,l+ u->val +r);
        return u->val+max(l,r);
    }
};
           
Leedcode高頻題刷刷刷ing
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* ans=0;
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        dfs(root,p,q);
        return ans;
    }
    int dfs(TreeNode* root,TreeNode* p,TreeNode* q){
        if(!root)return 0;
        int state=dfs(root->left,p,q);
        if(root==p)state|=1;
        else if(root==q)state|=2;
        state|=dfs(root->right,p,q);
        if(state==3&&!ans)ans=root;
        return state;
    }

};
           
Leedcode高頻題刷刷刷ing
DP 時間O(n),空間 O(1)O(1)
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int res = INT_MIN;
        for (int i = 0, last = 0; i < nums.size(); i ++ ) {
            last = nums[i] + max(last, 0);
            res = max(res, last);
        }
        return res;
    }
};
分治 時間O(n),空間O(logn)
           
class Solution {
public:

    struct Node {
        int sum, s, ls, rs;
    };

    Node build(vector<int>& nums, int l, int r) {
        if (l == r) {
            int v = max(nums[l], 0);
            return {nums[l], v, v, v};
        }

        int mid = l + r >> 1;
        auto L = build(nums, l, mid), R = build(nums, mid + 1, r);
        Node res;
        res.sum = L.sum + R.sum;
        res.s = max(max(L.s, R.s), L.rs + R.ls);
        res.ls = max(L.ls, L.sum + R.ls);
        res.rs = max(R.rs, R.sum + L.rs);
        return res;
    }

    int maxSubArray(vector<int>& nums) {
        int res = INT_MIN;
        for (auto x: nums) res = max(res, x);
        if (res < 0) return res;
        auto t = build(nums, 0, nums.size() - 1);
        return t.s;
    }
};

作者:yxc
連結:https://www.acwing.com/activity/content/code/content/362176/
來源:AcWing
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
           
Leedcode高頻題刷刷刷ing
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    unordered_map<int,int>hash;
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n=preorder.size();
        for(int i=0;i<n;i++)hash[inorder[i]]=i;
        return build(preorder,inorder,0,n-1,0,n-1);
    }
    TreeNode* build(vector<int>&preorder,vector<int>&inorder,int pl,int pr,int il,int ir){
        if(pl>pr)return NULL;
        auto root=new TreeNode(preorder[pl]);
        int k=hash[root->val];
        root->left=build(preorder,inorder,pl+1,k-il+pl,il,k-1);
        root->right=build(preorder,inorder,k-il+pl+1,pr,k+1,ir);
        return root;
    }
};
           
Leedcode高頻題刷刷刷ing
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    unordered_map<int,int>hash;
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        int n=inorder.size();
        for(int i=0;i<n;i++)hash[inorder[i]]=i;
        return build(inorder,postorder,0,n-1,0,n-1); 
    }
    TreeNode* build(vector<int>&inorder , vector<int>&postorder,int il,int ir,int pl,int pr){
        if(pl>pr)return nullptr;
        auto root=new TreeNode(postorder[pr]);
        int k=hash[root->val];
        root->left=build(inorder,postorder,il,k-1,pl,pl+k-1-il);
        root->right=build(inorder,postorder,k+1,ir,pr-ir+k,pr-1);
        return root;
    }
};
           
Leedcode高頻題刷刷刷ing
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    typedef pair<int,int>PII;
public:
    //我要寫一個cmp排序函數,使得vector按照
    //雙關鍵字排序【x,val】
    map<int,vector<int>>hash;
    unordered_map<int,int>depth;
    void dfs(TreeNode* root,int x,int y){
        if(!root)return;
        depth[root->val]=x;
        hash[y].push_back(root->val);
        dfs(root->left,x+1,y-1);
        dfs(root->right,x+1,y+1);
    }
    vector<vector<int>> verticalTraversal(TreeNode* root) {
        dfs(root,0,0);
        vector<vector<int>>ans;
        for(auto& [k,v] :hash){
            sort(v.begin(),v.end(),[&](int x,int y){
                if(depth[x]==depth[y])return x<y;
                return depth[x]<depth[y];
            });
            ans.push_back(v);
        }
        return ans;
    }
};
           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    bool dfs(TreeNode* root, TreeNode* subRoot){
        if(!root&&!subRoot)return 1;
        else if(!root||!subRoot||root->val!=subRoot->val)return 0;
        return dfs(root->left,subRoot->left)&dfs(root->right,subRoot->right);
    }
    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        if(!root&&subRoot)return 0;
        if(!root&&!subRoot)return 1;
        //else if(!root||!subRoot||root->val!=subRoot->val)return 0;
        //else if(root->val==subRoot->val)return dfs(root->left,subRoot->left)&dfs(root->right,subRoot->right);
        return isSubtree(root->left, subRoot)||isSubtree(root->right, subRoot)||dfs(root,subRoot);
    }
};

作者:我已經不想再做刺客了
連結:https://www.acwing.com/solution/content/67081/
來源:AcWing
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
           

這裡介紹第二種做法:樹上哈希

每棵樹的哈希值等于根的val+左子樹×質數P+右子樹×質數Q

有2個注意事項

1.P和Q不要取太大,P=131,Q=13,mod=1e7+7就好這樣就不會溢出

如果設定Q=133331,mod=1e9+7的話就會溢出int的範圍

2.如果子樹為空,不要傳回0,随便發揮一個數字12345就好了

因為傳回0的話可能與存在子樹val=0的情形相沖突

class Solution {
public:
    const int P=131,Q=13,mod=1e7+7;
    bool ans=0;
    int t=-1;//一開始設定為負數是為了讓t等于子樹的哈希值
    int dfs(TreeNode* root){
        if(!root)return 123;
        int L=dfs(root->left);
        int R=dfs(root->right);
        if(t==L||t==R)ans=1;
        return ((root->val + L*P %mod + R*Q %mod) %mod+mod)%mod;
    }
    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        t=dfs(subRoot);
        if(t==dfs(root))ans=1;
        return ans;
    }
};
           

輸入:root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2

輸出:[7,4,1]

解釋:

所求結點為與目标結點(值為 5)距離為 2 的結點,

值分别為 7,4,以及 1

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    unordered_map<TreeNode*,vector<TreeNode*>>mp;
    vector<int>ans;
    void dfs1(TreeNode* root){
        if(!root)return;
        if(root->left)
            mp[root].push_back(root->left),
            mp[root->left].push_back(root),
            dfs1(root->left);
        if(root->right)
            mp[root].push_back(root->right),
            mp[root->right].push_back(root),
            dfs1(root->right);
    }
    void dfs2(TreeNode* root,TreeNode*father,  int k){
        if(k==0)ans.push_back(root->val);
        else{
            for(auto son:mp[root]){
                if(son!=father)dfs2(son,root,k-1);
            }
        }
    }

    vector<int> distanceK(TreeNode* root, TreeNode* target, int k) {
        dfs1(root);
        dfs2(target,NULL,k);
        return ans;
    }
};
           

上面建的哈希表是指針

下面建的哈希表是節點的值

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int>ans;
    unordered_map<int,vector<int>>g;
    void dfs1(TreeNode* root){
        if(!root)return;
        int u=root->val;
        if(root->left){
            int L=root->left->val;
            g[u].push_back(L);
            g[L].push_back(u);
            dfs1(root->left);
        }
        if(root->right){
            int R=root->right->val;
            g[u].push_back(R);
            g[R].push_back(u);
            dfs1(root->right);
        }
    }
    void dfs2(int u,int fa,int k){
        if(k==0)ans.push_back(u);
        else{
            for(auto t:g[u]){
                if(t!=fa)dfs2(t,u,k-1);
            }
        }
    }
    vector<int> distanceK(TreeNode* root, TreeNode* target, int k) {
        dfs1(root);//建鄰接表g
        dfs2(target->val,-1,k);
        return ans;
    }
};
           

題目描述

給定兩個數組,請寫一個函數計算它們的交集。

注意:

每個數在結果中出現的次數,需要和它在兩個數組中出現的次數相同;

結果可以以任意順序輸出;

思考題:

如果給定的數組已經排好序,你可以怎樣優化你的算法?

如果數組nums1的長度小于數組nums2的長度,哪種算法更好?

如果數組nums2存儲在硬碟上,然而記憶體是有限的,你不能将整個數組都讀入記憶體,該怎麼做?

樣例

給定 nums1 = [1, 2, 2, 1], nums2 = [2, 2],

傳回 [2, 2].

算法

(哈希表) O(n+m)O(n+m)

首先先将nums1存入哈希表中,注意這裡要用unordered_multiset,而不是unordered_set,因為數組中含有重複元素。

然後周遊nums2,對于每個數 xx,如果 xx 出現在哈希表中,則将 xx 輸出,且從哈希表中删除一個 xx。

時間複雜度分析:假設兩個數組的長度分别是 n,mn,m。将nums1存入哈希表的計算量是 O(n)O(n),周遊nums2的計算量是 O(m)O(m),是以總時間複雜度是 O(n+m)O(n+m)。

思考題:

如果給定的數組已經排好序,你可以怎樣優化你的算法?

答:可以用雙指針掃描。這樣可以把空間複雜度降為 O(1)O(1),但時間複雜度還是 O(n)O(n);

如果數組nums1的長度小于數組nums2的長度,哪種算法更好?、

答:可以把nums1存入哈希表,然後周遊nums2。這樣可以使用更少的記憶體,但時空複雜度仍是 O(n)O(n);

如果數組nums2存儲在硬碟上,然而記憶體是有限的,你不能将整個數組都讀入記憶體,該怎麼做?

答:如果nums1可以存入記憶體,則可以将nums1存入哈希表,然後分塊将nums2讀入記憶體,進行查找;如果兩個數組都不能存入記憶體,可以先将兩個數組分别排序,比如可以用外排序,然後用類似于雙指針掃描的方法,将兩個數組分塊讀入記憶體,進行查找。

C++ 代碼

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        unordered_multiset<int> S;
        vector<int> res;
        for (int x : nums1) S.insert(x);
        for (int x : nums2)
            if (S.count(x))
            {
                res.push_back(x);
                S.erase(S.find(x));
            }
        return res;
    }
};

作者:yxc
連結:https://www.acwing.com/solution/content/372/
來源:AcWing
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
           
class Solution {
public:
    unordered_map<int,int>mp;
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        vector<int>ans;
        for(auto c:nums1)mp[c]++;
        for(auto c:nums2){
            if(mp[c]){
                ans.push_back(c);
                mp[c]--;
            }
        }
        return ans;
    }
};

作者:我已經不想再做刺客了
連結:https://www.acwing.com/solution/content/67123/
來源:AcWing
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,int>hash;
        vector<vector<string>>ans;
        int idx=0;
        for(auto str:strs){
            string s=str;
            sort(s.begin(),s.end());
            if(!hash.count(s)){
                hash[s]=idx++;
                ans.push_back({str});
            }
            else ans[hash[s]].push_back(str);
        }
        return ans;

    }
};
           
Leedcode高頻題刷刷刷ing
class RandomizedSet {
public:
    unordered_map<int,int>hash;
    vector<int>nums;
    /** Initialize your data structure here. */
    RandomizedSet() {

    }
    
    /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
    bool insert(int val) {
        if(!hash.count(val)){
            nums.push_back(val);
            hash[val]=nums.size()-1;
            return 1;
        }
        return 0;
    }
    
    /** Removes a value from the set. Returns true if the set contained the specified element. */
    bool remove(int val) {
        if(hash.count(val)){
            int x=val;
            int y=nums.back();
            int px=hash[x];
            int py=hash[y];
            swap(hash[x],hash[y]);
            swap(nums[px],nums[py]);
            hash.erase(x);
            nums.pop_back();
            return 1;
        }
        return 0;
    }
    
    /** Get a random element from the set. */
    int getRandom() {
        return nums[rand()%nums.size()];
    }
};

/**
 * Your RandomizedSet object will be instantiated and called as such:
 * RandomizedSet* obj = new RandomizedSet();
 * bool param_1 = obj->insert(val);
 * bool param_2 = obj->remove(val);
 * int param_3 = obj->getRandom();
 */
           

矩陣置為0

Leedcode高頻題刷刷刷ing

哈希表寫法

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int>S;
        int ans=0;
        for(auto x:nums)S.insert(x);
        for(auto x:nums){
            if(S.count(x)&&!S.count(x-1)){//這是一個起點,到達dp入口
                int y=x+1;
                S.erase(x);
                while(S.count(y))S.erase(y),y++;
                ans=max(ans,y-x);
            }
        }
        return ans;
    }
};
           

并查集寫法

class Solution {
public:
    unordered_map<int,int> a,b;
    int find(int x){
        return a.count(x)?a[x]=find(a[x]):x;
    }
    int longestConsecutive(vector<int>& nums) {
        for(auto i:nums)
            a[i]=i+1;
        int ans=0;
        for(auto i:nums){
            int y=find(i+1);
            ans=max(ans,y-i);
        }
        return ans;
    }
};
           
class LRUCache {
public:
    struct node{
        int key,val;
        node *left,*right;
        node(int key_,int val_):key(key_),val(val_),left(NULL),right(NULL){}
    }*L,*R;
    unordered_map<int,node*>hash;
    int n;
    void remove(node *p){
        p->left->right=p->right;
        p->right->left=p->left;
    }
    void insert(node *p){
        p->left=L;
        p->right=L->right;
        L->right->left=p;
        L->right=p;
    }
    LRUCache(int capacity) {
        n=capacity;
        L=new node(0,0);
        R=new node(0,0);
        L->right=R;
        R->left=L;
    }
    
    int get(int key) {
        if(!hash.count(key))return -1;
        auto p=hash[key];
        remove(p);
        insert(p);
        return p->val;
    }
    
    void put(int key, int value) {
        if(hash.count(key)){
            auto p=hash[key];
            p->val=value;
            remove(p);
            insert(p);
        }
        else{

            if(hash.size()==n){
                auto p=R->left;
                remove(p);
                hash.erase(p->key);
                delete p;
            }
            auto p=new node(key,value);
            insert(p);
            hash[key]=p;
        }
    }
};

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache* obj = new LRUCache(capacity);
 * int param_1 = obj->get(key);
 * obj->put(key,value);
 */

           
Leedcode高頻題刷刷刷ing
Leedcode高頻題刷刷刷ing
class Solution {
public:
    vector<int> largestDivisibleSubset(vector<int>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        vector<int>f(n);
        int k=0;
        for(int i=0;i<n;i++){
            for(int j=i-1;j>=0;j--){
                if(nums[i]%nums[j]==0)
                f[i]=max(f[i],f[j]+1);
            }
            if(f[k]<f[i])k=i;
        }
        vector<int>ans(1,nums[k]);
        while(f[k]>0){
            for(int i=0;i<n;i++){
                if(nums[k]%nums[i]==0&&f[k]==f[i]+1){
                    ans.push_back(nums[i]);
                    k=i;
                    break;
                }
            }
        }
        return ans;
    }
};
           
class Solution {
    public List<Integer> largestDivisibleSubset(int[] nums) {
    int n=nums.length;
    if(n==0)return new ArrayList<>();
    Arrays.sort(nums);
    int[] f=new int[n];
    Arrays.fill(f,1);
    int k=0;
    for(int i=1;i<n;i++){
        for(int j=0;j<i;j++){
            if(nums[i]%nums[j]==0)
            f[i]=Math.max(f[i] , f[j]+1);
        }
        if(f[k]<f[i])k=i;
    }
    //for(int i=0;i<n;i++)System.out.println(f[i]);
    List<Integer>ans=new ArrayList<>();
    ans.add(nums[k]);
    while(f[k]>1){
        for(int i=0;i<n;i++){
            if(nums[k]%nums[i]==0&&f[k]==f[i]+1){
                ans.add(nums[i]);
                k=i;
                break;
            }
        }
    }
    return ans;


    }
}
           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    
    const int mod=1e9+7;
    int numDecodings(string s) {
        int n=s.length();
        vector<int>f(n+1);
        f[0]=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=26;j++){
                char a=s[i-1];
                //f[i-1]部分
                if(j<10){
                    if(a=='*'||a==j+'0')
                    f[i]+=f[i-1];
                }
                //f[i-2]部分
                else if(i>=2){
                    char b=s[i-2];
                    int shi=j/10;
                    int ge=j%10;
                    if((b==shi+'0'||b=='*') &&(a==ge+'0'||a=='*'&&ge))
                    f[i]+=f[i-2];
                }
                f[i]%=mod;
            }
        }
        return f[n];
    }
};

           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    bool isMatch(string s, string p) {
        int n=s.size();
        int m=p.size();
        s=' '+s;
        p=' '+p;
        vector<vector<bool>>f(n+1,vector<bool>(m+1));
        f[0][0]=1;
        //i從0開始就是針對s=”aa”,p=”a*”這樣的條件,靠i=0時把f[0][2]設為true,使其符合題意。
        for(int i=0;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(j+1<=m&&p[j+1]=='*')continue;
                if(p[j]!='*'&&i)
                    f[i][j]=f[i-1][j-1]&&(s[i]==p[j]||p[j]=='.');
                else if(p[j]=='*')
                    f[i][j]=f[i][j-2]|| i&&f[i-1][j]&& (s[i]==p[j-1]||p[j-1]=='.');
            }
        }
        return f[n][m];
    }
};

           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    bool isMatch(string s, string p) {
        int n=s.length();
        int m=p.length();
        s=' '+s;
        p=' '+p;
        vector<vector<bool>>f(n+1,vector<bool>(m+1));
        f[0][0]=1;
        for(int i=0;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(p[j]!='*'&&i)f[i][j]=f[i-1][j-1]&&(s[i]==p[j]||p[j]=='?');
                else if(p[j]=='*')
                f[i][j]=f[i][j-1]||i&&f[i-1][j];
            }
        }
        return f[n][m];

    }
};

           
Leedcode高頻題刷刷刷ing

這道題很難

題解放這裡

class Solution {
public:
    int longestValidParentheses(string s) {
        int n=s.length();
        int ans=0;
        stack<int>stk;
        int start=0;
        for(int i=0;i<n;i++){
            if(s[i]=='(')stk.push(i);
            else{
                if(stk.empty())start=i+1;
                else{
                    stk.pop();
                    if(stk.empty())ans=max(ans,i-start+1);
                    else ans=max(ans,i-stk.top());
                }
            }
        }
        return ans;
    }
};
           
class Solution {
public:
    int longestValidParentheses(string s) {
        int n=s.length();
        int ans1=0;
        int start=0;
        int val=0;
        for(int i=0;i<n;i++){
            if(s[i]=='(')val++;
            else val--;
            if(val==0)ans1=max(ans1,i-start+1);
            else if(val<0){
                val=0;
                start=i+1;
            }
        }
        int ans2=0;
        start=n-1,val=0;
        for(int i=n-1;i>=0;i--){
            if(s[i]==')')val++;
            else val--;
            if(val==0)ans2=max(ans2,start-i+1);
            else if(val<0){
                val=0;
                start=i-1;
            }
        }
        return max(ans1,ans2);
    }
};
           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        vector<int>q;
        for(auto x:nums){
            if(q.empty()||x>q.back())q.push_back(x);
            else{
                if(x<=q[0])q[0]=x;
                else *lower_bound(q.begin(),q.end(),x)=x;
            }
        }
        return q.size();
    }
};
           
class Solution {
public:
    int maxEnvelopes(vector<vector<int>>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        vector<int>q(n);
        int ans=1;
        for(int i=0;i<n;i++){
            q[i]=1;
            for(int j=0;j<i;j++){
                if(nums[i][0]>nums[j][0] && nums[i][1]>nums[j][1]){
                    q[i]=max(q[i],q[j]+1);
                    ans=max(ans,q[i]);
                }
            }
        }
        return ans;
    }
};
           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    int maxProfit(vector<int>& a) {
        int n=a.size();
        int buy=1000000;
        int mai=0;
        for(auto x:a){
            mai=max(mai,x-buy);
            buy=min(buy,x);
        }
        return mai;
    }
};
           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    int maxProfit(vector<int>& a) {
        int n=a.size();
        vector<vector<int>>f(n,vector<int>(2));

        for(int i=0;i<n;i++)f[i][0]=f[i][1]=-0x3f3f3f3f;
        f[0][0]=0;
        f[0][1]=-a[0];
        for(int i=1;i<n;i++){
            f[i][0]=max(f[i-1][0] , f[i-1][1]+a[i]);
            f[i][1]=max(f[i-1][1] , f[i-1][0]-a[i]);
        }
        return f[n-1][0];
    }
};
           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    int f[100001][10][2];
    int k=2;
    int maxProfit(vector<int>& a) {
        int n=a.size();
        memset(f,-0x3f,sizeof f);
        f[0][0][0]=0;
        f[0][0][1]=-a[0];
        for(int i=1;i<n;i++){
            for(int j=k;j>=0;j--){
                if(j==0)f[i][j][0]=f[i-1][j][0];
                else f[i][j][0]=max(f[i-1][j][0] , f[i-1][j-1][1]+a[i]);

                f[i][j][1]=max(f[i-1][j][1] , f[i-1][j][0]-a[i]);
            }
        }
        int ans=0;
        for(int t=0;t<=k;t++)ans=max(ans , f[n-1][t][0]);
        return ans;
    }
};
           
Leedcode高頻題刷刷刷ing

這道題很精妙

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

在代碼中,j表示你在i的位置能挑到的最遠位置

i是一個逐漸右移的指針,如果i>j也就是說i能追上j的話

那就失敗,不能跳到這麼遠

則當i到第n個下标的時候,j從第n-1這個點能跳到的最遠路徑>i

return True

Leedcode高頻題刷刷刷ing
class Solution {
public:
    int jump(vector<int>& nums) {
        int n=nums.size();
        vector<int>f(n);
        for(int i=1,j=0;i<n;i++){
            while(j+nums[j]<i)j++;
            f[i]=f[j]+1;
        }
        return f[n-1];
    }
};
           
Leedcode高頻題刷刷刷ing
class Solution {
public:
    int minCut(string s) {
        int n=s.length();
        s=' '+s;
        vector<vector<bool>>g(n+1,vector<bool>(n+1));
        for(int j=1;j<=n;j++){
            for(int i=1;i<=j;i++){
                if(i==j)g[i][j]=1;
                else if(s[i]==s[j]){
                    if(i+1>=j)g[i][j]=1;
                    else g[i][j]=g[i+1][j-1];
                }
            }
        }
        vector<int>f(n+1,1e9);
        //f[i]表示将s[1~i]分成幾部分
        f[0]=0;
        for(int j=1;j<=n;j++){
            for(int i=1;i<=j;i++){
                if(g[i][j])
                f[j]=min(f[j],f[i-1]+1);
            }
        }
        return f[n]-1;

    }
};
           
Leedcode高頻題刷刷刷ing