1. 程式人生 > 其它 >LeetCode第226場周賽

LeetCode第226場周賽

技術標籤:leetcode

博主另外一個地址

5654. 盒子中小球的最大數量

題意:
問[l,r]區間中出現ok(x)最多的是
ok(x)定義為各位數字之和
思路
模擬即可
程式碼

class Solution {
public:
    
    int ok(int x) {
        int ans=0;
        while(x) {
            ans+=x%10;
            x/=10;
        }
        return ans;
    }
    
    int countBalls(int lowLimit, int highLimit)
{ map<int,int>mp; for(int i=lowLimit;i<=highLimit;i++) { int x=ok(i); mp[x]++; } int mx=0; for(auto item:mp) { mx=max(mx,item.second); } return mx; } };

5665. 從相鄰元素對還原陣列

題意
給定長度為n的二維陣列,第二維包含兩個數[ai,bi]即ai與bi緊鄰,讓我們構造出一個一維陣列,按照之前給定的相鄰方式,保證構造出來的陣列中每個數均不同,題目有解

思路
簡單離散化對ai和bi之間建立一條邊,即可直接dfs搜尋出符合題意的路徑

程式碼

class Solution {
public:
    int h[400005];
    int ne[400005];
    int e[400005];
    map<int,int>du;
    map<int,int>vis;
    vector<int>ans;
    int n,idx;
    
    void add(int x,int y){
        e[idx]=y;
        ne[idx]=h[x];
        h[x]=idx++
; } void dfs(int x,int cnt) { if(cnt>n) { return ; } for(int i=h[x];~i;i=ne[i]) { int j=e[i]; if(!vis[j]) { vis[j]=1; if(j>=100000) ans.push_back(j-200004); else ans.push_back(j); dfs(j,cnt+1); // ans.pop_back(); } } } vector<int> restoreArray(vector<vector<int>>& adjacentPairs) { int len=adjacentPairs.size(); n=len; memset(h,-1,sizeof h); for(int i=0;i<len;i++) { int x=adjacentPairs[i][0]; int y=adjacentPairs[i][1]; if(x<0) x+=200004; if(y<0) y+=200004; du[x]++; du[y]++; add(x,y); add(y,x); } for(auto item:du) { int y=item.second; if(y==1) { //cout<<item.first; if(item.first>100000) ans.push_back(item.first-200004); else ans.push_back(item.first); vis[item.first]=1; dfs(item.first,1); break; } } for(int i=0;i<ans.size();i++) { if(ans[i]<-100000) ans[i]=100000; } reverse(ans.begin(),ans.end()); return ans; } };

5667. 你能在你最喜歡的那天吃到你最喜歡的糖果嗎?

思路
貪心注意資料範圍為longlong
處理一個字首和陣列

ft //第ft型別的糖果
fd//第fd天
dc//每天最多吃dc顆糖果

如果要在第fd天吃到第ft型別的糖果需要滿足下述條件:

  1. (fd+1)*dc>sum[ft-1] 因為fd從第0開始算起,所以要滿足在fd+1天每天都吃最多的,其糖果數大於前ft-1個型別的糖果的總和
  2. fd<sum[ft] 即假設前fd天只吃一個糖果 要保證其值小於sum[ft]前ft個糖果總數

程式碼

class Solution {
public:
    long long int sum[100005];
    vector<bool> canEat(vector<int>& candiesCount, vector<vector<int>>& queries) {
        int lencand=candiesCount.size();
        for(int i=0;i<lencand;i++) {
            if(i) sum[i]=sum[i-1]+candiesCount[i];
            else sum[i]=candiesCount[i];
        }
        vector<bool>ans;
        for(int i=0;i<queries.size();i++) {
            long long int ft=queries[i][0];//第ft型別的糖果
            long long int fd=queries[i][1];//第fd天
            long long int dc=queries[i][2];//每天最多吃dc顆糖果
            //cout<<fd*dc<<"  "<<sum[ft-1]<<'\n';
            if(ft) {
                //cout<<(fd+1)*dc<<"  "<<sum[ft-1]<<"  "<<sum[ft]<<"  "<<fd<<'\n';
                if((fd+1)*dc>sum[ft-1]&&fd<sum[ft]) ans.push_back(true);
                else ans.push_back(false);
            }
            else {
                if((fd+1)<=sum[ft]) ans.push_back(true);
                else ans.push_back(false);
            }
            
        }
        return ans;
    }
};

5666. 迴文串分割 IV

給你一個字串 s ,如果可以將它分割成三個 非空 迴文子字串,那麼返回 true ,否則返回 false 。

當一個字串正著讀和反著讀是一模一樣的,就稱其為 迴文字串 。

思路
處理一個f[l][r]陣列,表示區間[l,r]能否形成一個迴文字串然後列舉兩個分割點
即可 i,j使得f[l][i]、f[i+1][j]、f[j+1][r]均可組成一個迴文字串

對於f[l][r],

  1. 若l==r則f[l][r]=true
  2. 若r==l+1則f[l][r]=s[l]==s[r]
  3. 若r>l+1則f[l][r]=s[l]==s[r]&&f[l+1][r-1]
    為了保證f[l+1][r-1]狀態要在f[l][r]狀態前計算出來 因此l可以採用從大到小進行列舉

程式碼

class Solution {
public:
    bool f[2002][2002];
    bool checkPartitioning(string s) {
        int n=s.length();
        for(int l=n-1;l>=0;l--) {
            for(int r=l;r<n;r++) {
                if(l==r)f[l][r]=true;
                else if(r==l+1) f[l][r]=(s[l]==s[r]);
                else f[l][r]=s[l]==s[r]&&f[l+1][r-1];
            }
        }
        for(int i=0;i<n;i++) {
            for(int j=i+1;j<n;j++) {
                if(f[0][i]&&f[i+1][j]&&f[j+1][n-1]) return true;
            }
        }
        return false;
    }
};