【Leetcode】每日一题打卡(64)

1619. 删除某些元素后的数组均值 - 简单ac 

class Solution {
public:
    double trimMean(vector<int>& arr) {
        sort(arr.begin(),arr.end());
        int idx=arr.size()*0.05;
        double sum=0;
        for(int i=idx;i<arr.size()-idx;i++) sum+=arr[i];
        return sum/(arr.size()-idx*2);
    }
};

672. 灯泡开关 Ⅱ - 中等 - 思维

class Solution {
public:
    int flipLights(int n, int presses) {
        if(presses==0) return 1;
        else if(n==1) return 2;
        else if(n==2) return presses==1?3:4;
        else
            return presses==1?4:presses==2?7:8;
    }
};

850. 矩形面积 II - 困难

typedef long long LL;
typedef pair<int,int>PII;
const int mod=1e9+7;
class Solution {
public:
    LL calc(vector<vector<int>>&rts,int a,int b)
    {
        vector<PII>q;
        for(auto x:rts)
        {
            if(x[0]<=a&&x[2]>=b)
                q.push_back({x[1],x[3]});
        }
        sort(q.begin(),q.end());
        LL res=0,st=-1e8,ed=-1e8;
        for(auto x:q)
        {
            if(x.first>ed)
            {
                if(ed!=-1e8)res+=ed-st;
                st=x.first,ed=x.second;
            }
            else if(x.second>ed)ed=x.second;
        }
        res+=ed-st;
        return res*(b-a);
    }
    int rectangleArea(vector<vector<int>>& rts) {
        vector<int>xs;
        for(auto x:rts)xs.push_back(x[0]),xs.push_back(x[2]);
        sort(xs.begin(),xs.end());
        LL res=0;
        for(int i=1;i<xs.size();i++)
            res+=calc(rts,xs[i-1],xs[i]);
        return res%mod;
    }
};



1624. 两个相同字符之间的最长子字符串 - 简单ac

class Solution {
public:
    int maxLengthBetweenEqualCharacters(string s) {
        unordered_map<char,int>mp;
        int res=-1,t;
        for(int i=0;i<s.size();i++)
        {
            if(mp.count(s[i])) t=i-mp[s[i]]-1,res=max(res,t);
            if(!mp.count(s[i])) mp[s[i]]=i;
        }
        return res;
    }
};



1636. 按照频率将数组升序排序 - 简单ac

class Solution {
public:

    vector<int> frequencySort(vector<int>& nums) {
        unordered_map<int,int>mp;
        for(int x:nums) mp[x]++;
        sort(nums.begin(),nums.end(),[&](int a, int b)
        {
            if(mp[a]!=mp[b]) return mp[a]<mp[b];
            return a>b;
        });
        return nums;
    }
};

698. 划分为k个相等的子集 - 中等 dfs

class Solution {
public:
    bool canPartitionKSubsets(vector<int>& nums, int k) {
        int n=nums.size();
        int sum=0;
        for(auto x:nums) sum+=x;
        if(sum%k) return false;
        int ave=sum/k;
        sort(nums.begin(),nums.end());
        if(ave<nums[n-1]) return false; //如果序列中最大的数都比ave大 则不能平分
        vector<int>b;
        for(int i=0;i<k;i++) b.push_back(ave);
        return dfs(nums,n-1,k,b);
    }

    bool dfs(vector<int>&nums,int cur,int k,vector<int>&b)
    {
        if(cur<0) return true; //如果数组全部遍历完 说明所有数都放进桶了
        for(int i=0;i<k;i++)
        {
            if(i>0&&b[i]==b[i-1]) continue; //如果该情况和上一个是相同的 则不用向下遍历

            if(b[i]==nums[cur]||b[i]-nums[cur]>=nums[0])//刚好能放桶里 或 一个桶能放多个
            {
                b[i]-=nums[cur];
                if(dfs(nums,cur-1,k,b)) return true;
                b[i]+=nums[cur];
            }
        }            
        
        return false;
    }
};

1640. 能否连接形成数组 - 简单 - 哈希表

哈希表

class Solution {
public:
    bool canFormArray(vector<int>& arr, vector<vector<int>>& pieces) {
        unordered_map<int,int> m;
        for(int i=0;i<pieces.size();i++) //把每一个数组第一个数作为索引
            m[pieces[i][0]]=i;
        for(int i=0;i<arr.size(); ) 
        {
            if(!m.count(arr[i])) return false;
            int k=m[arr[i]];
            for(auto x:pieces[k]) 
                if(arr[i++]!=x) return false;
        }
        return true;
    }
};

1652. 拆炸弹 - 简单 - 前缀和

前缀和

循环数组求和可以把该数组弄成两份 预处理前缀和

比如:5 7 1 4 5 7 1 4

注意sum[0]=0

  • 若k>0 则范围为【i+1, i+k+1】

  • 如 5 7 1 4 5 7 1 4  i=0,k=3时,res = sum[i+k+1] - sum[i+1]

  • 若k<0 则范围为【i+n+k, i+n】

  • 如 5 7 1 4 5 7 1 4  i=0,k=-2时,res = sum[i+n] - sum[i+n+k]

class Solution {
public:
    vector<int> decrypt(vector<int>& code, int k) {
        int n=code.size();
        vector<int>res(n,0);
        vector<int>sum(2*n+10,0);
        if(k==0) return res;
        for(int i=1;i<=n*2;i++) sum[i]=sum[i-1]+code[(i-1)%n];
        for(int i=0;i<n;i++)
            if(k<0) res[i]=sum[i+n]-sum[i+n+k];
            else res[i]=sum[i+k+1]-sum[i+1];
        return res;
    }
};

拼接数组解决循环数组

class Solution {
public:
    vector<int> decrypt(vector<int>& code, int k) {
        int n=code.size();
        vector<int>res,v;
        for(int i=0;i<3;i++)
            for(auto x:code) v.push_back(x);
        for(int i=n;i<2*n;i++)
        {
            int sum=0;
            if(k>0) for(int j=i+1;j<i+1+k;j++) sum+=v[j];
            else if(k<0) for(int j=i+k;j<i;j++) sum+=v[j];
            res.push_back(sum);
        }
        return res;
    }
};

788. 旋转数字 - 中等 - 模拟

枚举1~n每一个数 先用数组记录每个数字反转情况

比如2反转后为5     7反转后不是数字 则记录-1

用y记录反转后的数 如果中间出现反转后非数字的数 直接return false

最后x和y比较 如果x!=y 说明是有效数 cnt++

class Solution {
public:
    int rotatedDigits(int n) {
        int cnt=0;
        for(int i=1;i<=n;i++) cnt+=check(i);
        return cnt;
    }

    bool check(int x)
    {
        vector<int> d={0,1,5,-1,-1,2,9,-1,8,6};
        int t=x,y=0,k=1;
        while(t)
        {
            int p=t%10;
            if(d[p]==-1) return false;
            y+=k*d[p];
            t/=10;
            k*=10;
        }
        return x!=y;
    }
};

面试题 17.09. 第 k 个数 - 中等 - dp 三指针 / 小顶堆

方法一:三指针 dp

class Solution {
public:
    int getKthMagicNumber(int k) {
        vector<int>dp(k+1);
        dp[1]=1;
        int p1=1,p2=1,p3=1;
        for(int i=2;i<=k;i++)
        {
            dp[i]=min({dp[p1]*3,dp[p2]*5,dp[p3]*7});
            if(dp[i]==dp[p1]*3) p1++;
            if(dp[i]==dp[p2]*5) p2++;
            if(dp[i]==dp[p3]*7) p3++;
        }
        return dp[k];
    }
};

方法二:小顶堆 

用哈希表去重

class Solution {
public:
    int getKthMagicNumber(int k) 
    {
        int res;
        int help[3]={3,5,7};
        if(k==1)return 1;
        priority_queue<int,vector<int>,greater<int>>que;
        set<int> st;//排重
        que.push(3);
        que.push(5);
        que.push(7);
        int index=1;
        while(index<k)
        {
            int tmp=que.top();
            que.pop();
            res=tmp;
            index++;
            for(auto a:help)
            {
                if((long long)a*tmp>INT_MAX)continue;//超出范围,禁止入内
                if(st.count(a*tmp))continue;//出现过,跳过
                else st.insert(a*tmp);
                que.push(a*tmp);
            }
        }
        return res;

    }
};

同类型拓展—— 264. 丑数 II 

 面试题 01.08. 零矩阵 - 中等 - vector存pair

class Solution {
public:
    void setZeroes(vector<vector<int>>& a) {
        int m=a.size(),n=a[0].size();
        vector<pair<int,int>> v;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(a[i][j]==0) v.push_back({i,j});
        for(auto x:v)
        {
            for(int i=0;i<m;i++) a[i][x.second]=0;
            for(int i=0;i<n;i++) a[x.first][i]=0;
        }
    }
};

1694. 重新格式化电话号码 - 简单ac

class Solution {
public:
    string reformatNumber(string number) {
        vector<char>v;
        int cnt=0,k;
        string res;
        if(number.size()<4) return number;
        for(auto x:number) if(x>='0'&&x<='9') v.push_back(x);
        int t=v.size();
        for(int i=0;i<v.size();i++)
        {
            if(cnt==3) t-=3,cnt=0,res+='-';
            if(t==4) 
            {
                k=i;
                break;
            }
            res+=v[i];
            cnt++;
        }
        for(int i=k;i<v.size();i++) 
        {
            res+=v[i];
            if(i==k+1) res+='-';
        }
    return res;
    }
};

777. 在LR字符串中交换相邻字符 - 中等 - 双指针

class Solution {
public:
    bool canTransform(string start, string end) {
        int n=start.size();
        int i=0,j=0;
        while(i<n||j<n)
        {
            //跳过X
            while(start[i]=='X') i++;
            while(end[j]=='X') j++;
            if(start[i]!=end[j]) return false; //如果去掉X不相等 则说明不是
            //因为R只能向右移动 L只能向左移动
            if((start[i]=='R'&&i>j)||(start[i]=='L'&&i<j)) return false;
            i++,j++; //继续向后遍历
        }
        return true;
    }
};

1784. 检查二进制字符串字段 - 简单 - 思维

class Solution {
public:
    bool checkOnesSegment(string s) {
        return s.find("01")==s.npos; //s.npos表示不存在的位置
    }
};

921. 使括号有效的最少添加 - 中等ac

class Solution {
public:
    int minAddToMakeValid(string s) {
        stack<char>st;
        int cnt=0;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]=='(') st.push(s[i]),cnt++;
            if(s[i]==')') 
                if(st.empty()) cnt++;
                else if(!st.empty()) cnt--,st.pop();
        }
        return cnt;
    }
};

811. 子域名访问计数 - 中等 - 模拟+string 操作

class Solution {
public:
    vector<string> subdomainVisits(vector<string>& cp) {
        unordered_map<string,int>mp;
        for(auto s:cp)
        {
            int pos=s.find(' ');
            int cnt=stoi(s.substr(0,pos)); //记录次数 stoi()把n进制字符串转化为十进制
            while(pos!=-1)
            {
                mp[s.substr(pos+1)]+=cnt;
                pos=s.find('.',pos+1); //pos更新为下一个点的下标  s.find(a,b)-从b的位置开始找a
            }
        }
        vector<string>res;
        for(auto &[s,cnt]:mp)
            res.push_back(to_string(cnt)+' '+s); //to_string()将数字转化为字符
        return res;
    }
};

927. 三等分 - 困难 - 思维+模拟

class Solution {
public:
    vector<int> threeEqualParts(vector<int>& a) {
        int sum=0;
        for(auto x:a) sum+=x;
        if(sum%3!=0) return {-1,-1}; //如果1的个数不能均分为3份 则无解
        if(sum==0) return {0,2}; //如果序列里没有1 则任意分

        //把f定位到第1个1出现的位置 s定位到第part+1个1出现位置 t定位到第part*2+1个1出现位置
        //也就是把1均分成3段
        int part=sum/3;
        int f=0,s=0,t=0,cnt=0;
        for(int i=0;i<a.size();i++)
            if(a[i]==1)
            {
                if(cnt==0) f=i;
                else if(cnt==part) s=i;
                else if(cnt==part*2) t=i;
                cnt++;
            }
        //因为数组末尾无法改变 所以【t,a.size()-1】表示的二进制值可以固定
        int len=a.size()-t;
        //判断【f,f+len】【s,s+len】【t,t+len】是否完全相同
        if(f+len<=s && s+len<=t)
        {
            int i=0;
            while(t+i<a.size())
            {
                if(a[f+i]!=a[s+i] || a[f+i]!=a[t+i]) return {-1,-1};
                i++;
            }
            return {f+len-1,s+len};
        }
        return {-1,-1};
    }
};

1800. 最大升序子数组和 - 简单 - dp

dp

class Solution {
public:
    int maxAscendingSum(vector<int>& a) {
        int n=a.size();
        vector<int>f(n);
        int res=a[0];
        f[0]=a[0];
        //f[i]为以元素i为结尾时可得的子数组最大值
        for(int i=1;i<n;i++)
        {
            if(a[i]>a[i-1]) f[i]=max(a[i],f[i-1]+a[i]);
            else f[i]=a[i];
            res=max(res,f[i]);
        }
        return res;
    }
};

模拟

class Solution {
public:
    int maxAscendingSum(vector<int>& a) {
        int n=a.size();
        int res=a[0],sum=a[0];
        for(int i=1;i<n;i++)
        {
            if(a[i]>a[i-1]) sum+=a[i];
            else sum=a[i];
            res=max(res,sum);
        }
        return res;
    }
};

870. 优势洗牌 - 中等 - 田忌赛马 - 大顶堆

class Solution {
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
        priority_queue<int> q;//默认大顶堆
        for(auto &x:nums1) q.push(x);
        vector<int> idx(nums2.size());
        iota(idx.begin(),idx.end(),0);
        sort(idx.begin(),idx.end(),[&](int i,int j){return nums2[i]>nums2[j];});//数组2用下标从大到小排序
        vector<int> ans(nums1.size(),-1);
        for(auto i:idx) 
            if(q.top()>nums2[i]) 
            {
                ans[i]=q.top();
                q.pop();
            }
        for(auto &x:ans)
            if(x==-1) x=q.top(), q.pop();
        return ans;
    }
};
class Solution {
public:
    vector<int> advantageCount(vector<int>& a, vector<int>& b) {
        int n=a.size();
        vector<vector<int>>g(n,vector<int>(2));
        for(int i=0;i<n;i++)g[i][0]=i,g[i][1]=b[i];
        sort(g.begin(),g.end(),[&](vector<int>a,vector<int>b){
            return a[1]<b[1];
        });
        sort(a.begin(),a.end());
        vector<int>res(n,-1);
        vector<int>v;
        for(int i=0,j=0;i<n;i++)
            if(a[i]>g[j][1])res[g[j][0]]=a[i],j++;
            else v.push_back(a[i]);
        int cnt=0;
        for(auto &x:res)
            if(x==-1)x=v[cnt++];
        return res;
    }
};

856. 括号的分数 - 中等 - 思维

class Solution {
public:
    int scoreOfParentheses(string s) {
        int res=0,cnt=0;
        for(int i=0;i<s.size();i++)
        {
            s[i]=='('? cnt++:cnt--;
            if(s[i]==')'&&s[i-1]=='(') res+=1<<cnt;
        }
        return res;
    }
};

801. 使序列递增的最小交换次数 - 困难 - dp

class Solution {
public:
    int minSwap(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int a = 0, b = 1;
        for (int i = 1; i < n; i++) {
            int at = a, bt = b;
            a = b = n;
            if (nums1[i] > nums1[i - 1] && nums2[i] > nums2[i - 1])  {
                a = min(a, at);
                b = min(b, bt + 1);
            }
            if (nums1[i] > nums2[i - 1] && nums2[i] > nums1[i - 1]) {
                a = min(a, bt);
                b = min(b, at + 1);
            }
        }
        return min(a, b);
    }
};

1790. 仅执行一次字符串交换能否使两个字符串相等 - 简单

思路:

标定起始不相同位st和末尾不相同位ed 最后交换这两个位置的字母

如果交换完相同,说明仅执行一次交换可以使两字符串相等

class Solution {
public:
    bool areAlmostEqual(string s1, string s2) {
        int n=s1.size();
        if(s1.size()!=s2.size()) return false;
        int st=-1,ed=-1;
        for(int i=0;i<n;i++)
        {
            if(s1[i]!=s2[i]&&st==-1) st=i;
            else if(s1[i]!=s2[i]) ed=i;
        }
        if(~st&&~ed) swap(s1[st],s1[ed]);
        return s1==s2;
    }
};

817. 链表组件 - 中等 - 哈希表

set.emplace() 是向set容器中插入值

题意:

在一段链表里找连续段数 例如链表1—2—3—4

nums[ 1,3,4 ] 因为1是一段 3-4是一段 所以结果为2

思路:

用哈希表set存nums出现的结点

遍历链表,如果链表中存在set里出现的值,且是开始结点,res++

如果遍历到该结点nums中不存在,则截断

class Solution {
public:
    int numComponents(ListNode* head, vector<int>& nums) 
    {
        set<int>mp;
        for(auto n:nums)
        {
            mp.emplace(n);
        }
        int res=0;
        bool f=true;
        while(head!=NULL)
        {
            if(mp.count(head->val)) 
            {
                if(f) f=false,res++;
            }else f=true;

            head=head->next;
        }
        return res;
    }
};

769. 最多能完成排序的块 - 中等 - 贪心

题意:

给定一个长度为 n 的整数数组 arr ,它表示在 [0, n - 1] 范围内的整数的排列。

我们将 arr 分割成若干 块 (即分区),并对每个块单独排序。将它们连接起来后,使得连接的结果和按升序排序后的原数组相同。

返回数组能分成的最多块数量。

思路:

由于 arrarr 是 [0,..,n-1]的一个排列,若已遍历过的数中的最大值 mx 与当前遍历到的下标 i 相等,说明可以进行一次分割,累加答案

class Solution {
public:
    int maxChunksToSorted(vector<int>& a) {
        int m=0,res=0;
        for(int i=0;i<a.size();i++)
        {
            m=max(m,a[i]);
            if(m==i) res++;
        }
        return res;
    }
};

940. 不同的子序列 II - 困难 - dp

题意:

给定一个字符串 s,计算 s 的 不同非空子序列 的个数。因为结果可能很大,所以返回答案需要对 10^9 + 7 取余 。

字符串的 子序列 是经由原字符串删除一些(也可能不删除)字符但不改变剩余字符相对位置的一个新字符串。

思路:

为什么 之前的curAns=新增的newcount呢?

相当于新增的这个字母本身+跟之前的组合

看第三步:之前的组合是 a、b、ab 则新增的就是  ac、bc、abc 再加上本身 c

因此curAns=newcount

class Solution {
public:
    int distinctSubseqII(string s) {
        int mod=(int)1e9 + 7;
        int n=s.length();
        vector<int>pre(26);
        int curAns=1;
        for (int i=0; i<n; i++) 
        {
            //新增的个数
            int newCount=curAns;
            //当前序列的个数 = 之前的 + 新增的 - 重复的
            curAns=((curAns+newCount)%mod-pre[s[i]-'a']%mod+mod)%mod;
            //记录当前字符的 新增值
            pre[s[i]-'a']=newCount;
        }
        //减去空串
        return curAns-1;
    }
};

1441. 用栈操作构建数组 - 中等ac - 指针

思路:

从1~n遍历

如果能对的上 输出Push 并移动a数组的指针

如果对不上 说明先Push再Pop 不移动指针 继续跟下一个数比较

如果指针越界 则跳出循环

class Solution {
public:
    vector<string> buildArray(vector<int>& a, int n) {
        int cnt=0;
        vector<string>s;
        for(int i=1;i<=n;i++)
        {
            if(cnt>a.size()-1) break;
            
            if(a[cnt]==i) s.push_back("Push"),cnt++;
            else if(a[cnt]!=i) s.push_back("Push"),s.push_back("Pop");
        }
        return s;
    }
};

886. 可能的二分法 - 中等 - 二分图模板题

dfs:

class Solution {
public:
    static const int N=20010,M=N<<1;//N是点的个数 M是边的条数 因为是无向图 所以边要双倍
    int h[N],e[M],ne[M],idx;
    int st[N];

    void add(int a,int b)
    {
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }

    bool dfs(int u,int c)
    {
        st[u]=c;//给这个点染色
        for(int i=h[u];~i;i=ne[i])//遍历这个点相邻的点
        {
            int j=e[i];
            if(!st[j])//如果该点未染色 递归染色
            {
                if(!dfs(j,3-c)) return false;//实现1、2两种颜色的转换
            }
            else if(st[j]==st[u]) return false;//如果染过色且染过的色和相邻点相同则不能二分
        }
        return true;
    }

    bool possibleBipartition(int n, vector<vector<int>>& dis) {
        memset(h,-1,sizeof h);
        for(auto p:dis)
        {
            int a=p[0],b=p[1];
            add(a,b);
            add(b,a);
        }
        for(int i=1;i<=n;i++)
            if(!st[i])
                if(!dfs(i,1)) return false;//如果没有染色成功 则说明无法二分图
        return true;
    }
};

bfs:

 

class Solution {
public:
    static const int N=20010,M=N<<1;//N是点的个数 M是边的条数 因为是无向图 所以边要双倍
    typedef pair<int,int> PII;//<点的编号,颜色>
    int h[N],e[M],ne[M],idx;
    int st[N];

    void add(int a,int b)
    {
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }

    bool bfs(int u)
    {
        PII q[N];
        int hh=0,tt=0;
        q[0]={u,1};
        st[u]=1;

        while(hh<=tt)
        {
            auto t=q[hh++];
            int v=t.first,c=t.second;
            for(int i=h[v];~i;i=ne[i])
            {
                int j=e[i];
                if(!st[j])//如果相邻点未染色 则染上相反颜色并入队
                {
                    st[j]=3-c;
                    q[++tt]={j,3-c};
                }
                else if(st[j]==c) return false;
            }
        }
        return true;
    }

    bool possibleBipartition(int n, vector<vector<int>>& dis) {
        memset(h,-1,sizeof h);
        for(auto p:dis)
        {
            int a=p[0],b=p[1];
            add(a,b);
            add(b,a);
        }
        for(int i=1;i<=n;i++)
            if(!st[i])
                if(!bfs(i)) return false;//如果没有染色成功 则说明无法二分图
        return true;
    }
};

904. 水果成篮 - 中等 - 滑动窗口+哈希表计数

思路:

维护一个窗口 如果窗口内水果种类>2 则删掉开头的一种水果

每次循环 取最大值

class Solution {
public:
    int totalFruit(vector<int>& f) {
        int res=0,t=0;
        unordered_map<int,int>mp;
        for(int i=0;i<f.size();i++)
        {
            mp[f[i]]++;
            while(mp.size()>2)
            {
                int y=f[t++];
                if(--mp[y]==0) mp.erase(y);//一旦窗口里水果种类>2 则删掉开头的一种水果
            }
            res=max(res,i-t+1);
        }
        return res;
    }
};
class Solution {
    public int totalFruit(int[] fruits) {
        Map<Integer, Integer> cnt = new HashMap<>();
        int ans = 0;
        for (int i = 0, j = 0; i < fruits.length; ++i) {
            int x = fruits[i];
            cnt.put(x, cnt.getOrDefault(x, 0) + 1);
            while (cnt.size() > 2) {
                int y = fruits[j++];
                cnt.put(y, cnt.get(y) - 1);
                if (cnt.get(y) == 0) {
                    cnt.remove(y);
                }
            }
            ans = Math.max(ans, i - j + 1);
        }
        return ans;
    }
}

902. 最大为 N 的数字组合 - 困难 - 数位dp

class Solution {
    public int atMostNGivenDigitSet(String[] digits, int n) {
        char[] nc = String.valueOf(n).toCharArray();
        int result = 0, ncl = nc.length, dl = digits.length;
        for (int i = 1; i < ncl; i++) result += Math.pow(dl, i); // 先对【非最高位】的其他位,可组装的数字进行统计
        for (int i = 0; i < ncl; i++) {
            boolean compareNext = false; // 是否需要对比下一个数字
            for (String digit : digits) {
                char dc = digit.charAt(0); // 将String转换为char
                if (dc < nc[i]) result += Math.pow(dl, ncl - i - 1);
                else {
                    if (dc == nc[i]) compareNext = true; break;
                }
            }
            if (!compareNext) return result;
        }
        return ++result; // 如果到最后1位依然满足compareNext,因为最后1位无法再向后对比了,所以最终结果+1
    }
}

1700. 无法吃午餐的学生数量 - 简单 - 模拟

思路:

统计学生喜欢吃的三明治种类

因为三明治的顺序不能动

遍历三明治 如果有一种三明治大家都不喜欢 那么这个三明治卡在栈顶 后面的人都吃不了

直接返回后面没吃到的人就可以了

class Solution {
    public int countStudents(int[] stu, int[] san) {
        int[] cnt=new int[2];
        for(int x:stu) cnt[x]++;
        for(int i=0;i<san.length;i++)
            if(cnt[san[i]]--==0) return san.length-i;
        return 0;
    }
}

779. 第K个语法符号 - 中等 - 思维+递归+位运算

思路:

力扣

根据图可以发现:每个位置的值取决于自己的父结点

  • 如果是左孩子则与父结点值相同
  • 如果是右孩子则和父节点相反

如果是第一层,则返回0,否则

  • 求它(n,k)父节点的位置,就是(n-1,(k+1)/2这个意思是k/2向上取整
  • 接着判断是左孩子还是右孩子:如果k是奇数,则和父节点相同,否则相反
  • 也就是1^(k%2) :如果k是奇数 则1异或1为0
  • 1^(k%2)^kthGrammar(n-1,(k+1)/2);     0异或任何数都不改变值
  • 也就是如果k是奇数 即左孩子 值和父节点相同
class Solution {
    public int kthGrammar(int n, int k) {
        return n==1?0:(k%2)^1^kthGrammar(n-1,(k+1)/2);
    }
}

901. 股票价格跨度 - 中等 - 单调栈

思路:

本题其实就是要求左边离自己最近的比自己大的价格的距离

例如:[100, 80, 60, 70, 60, 75, 85]

答案:[1, 1, 1, 2, 1, 4, 6]

所以利用单调栈

查询某个价格时,把比它小的价格都pop掉,并累加这些价格的w

用单调栈维护一个单调递减的价格序列,并且对于每个价格,存储一个 w 表示它离上一个价格之间(即最近的一个大于它的价格之间)的天数。如果是栈底的价格,则存储它本身对应的天数。

  • 例如 [11, 3, 9, 5, 6, 4, 7] 对应的单调栈为 (11, weight=1), (9, weight=2), (7, weight=4)。

当我们得到了新的一天的价格,例如 10,我们将所有栈中所有小于等于 10 的元素全部取出,将它们的 w 进行累加,再加上 1 就得到了答案。在这之后,我们把 10 和它对应的 w 放入栈中,得到 (11, weight=1), (10, weight=7)

class StockSpanner {
    Deque<Integer> p,day;
    public StockSpanner() {
        p=new LinkedList<>();
        day=new LinkedList<>();
    }
    
    public int next(int price) {
        int w=1; //包括今天
        while(!p.isEmpty()&&p.peek()<=price)
        {
            p.pop();
            w+=day.pop();
        }
        p.push(price);
        day.push(w);
        return w;
    }
}

1235. 规划兼职工作 - 困难 - dp+二分

class Solution {
    public int jobScheduling(int[] startTime, int[] endTime, int[] profit) {
        int n = profit.length;
        int[][] jobs = new int[n][3];
        for (int i = 0; i < n; ++i) {
            jobs[i] = new int[] {startTime[i], endTime[i], profit[i]};
        }
        Arrays.sort(jobs, (a, b) -> a[1] - b[1]);
        int[] dp = new int[n + 1];
        for (int i = 0; i < n; ++i) {
            int j = search(jobs, jobs[i][0], i);
            dp[i + 1] = Math.max(dp[i], dp[j] + jobs[i][2]);
        }
        return dp[n];
    }

    private int search(int[][] jobs, int x, int n) {
        int left = 0, right = n;
        while (left < right) {
            int mid = (left + right) >> 1;
            if (jobs[mid][1] > x) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
}

1768. 交替合并字符串 - 简单 - 模拟string

class Solution {
    public String mergeAlternately(String s1, String s2) {
        StringBuilder s=new StringBuilder();
        int n1=s1.length(),n2=s2.length();
        int l=0,r=0,cnt=1;
        while(l<n1&&r<n2)
        {
            if(cnt%2==1) s.append(s1.charAt(l++));
            else s.append(s2.charAt(r++));
            cnt++;
        }
        while(l<n1) s.append(s1.charAt(l++));
        while(r<n2) s.append(s2.charAt(r++));
        return s.toString();
    }
}

915. 分割数组 - 中等 - 思维

题意:

给定一个数组 nums ,将其划分为两个连续子数组 left 和 right, 使得:

  • left 中的每个元素都小于或等于 right 中的每个元素。
  • left 和 right 都是非空的。
  • left 的长度要尽可能小。

在完成这样的分组后返回 left 的 长度 

思路:

记录left数组的最大值 如果当前元素小于left数组的最大值 记录下标

例如:

[5,0,3,6,2,8,7] 随时更新左数组的最大值
class Solution {
    public int partitionDisjoint(int[] a) {
       if(a.length==0) return 0;

        int leftMax=a[0];
        int max=a[0];
        int idx=0;
        //如果当前元素小于左边数组的最大值时,将分界点的位置更新为当前元素的位置
        for (int i=0;i<a.length;i++) 
        {
            max=Math.max(max,a[i]);
            if(a[i]<leftMax) 
            {
                leftMax=max;
                idx=i;
            }
        }
        return idx+1; 
    }
}

934. 最短的桥 - 中等 - dfs+bfs

思路:

用dfs把第一个岛屿先标成2 

初始化dist数组全为-1

另一个岛屿的dist数组全为0

用bfs拓展另一个岛屿  一旦拓展到另一个岛屿返回dist[i][j];

最后结果-1

class Solution {
    int m,n;
    int[][] dist;//不能在这里初始化
    int[] dx=new int[]{-1,0,1,0},dy=new int[]{0,1,0,-1};

    public int shortestBridge(int[][] g) 
    {
        m=g.length;
        n=g[0].length;
        dist=new int[m][n];
        int f=1;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(g[i][j]==f) //找第一个岛屿
                {
                    dfs(i,j,g);
                    f=-1;//防止记录另一个岛屿
                }
        return bfs(g)-1;
    }

    public void dfs(int x,int y,int[][] g)//java传递数组 方法修改数组 会直接修改数组的值
    {
        g[x][y]=2;
        for(int i=0;i<4;i++)
        {
            int a=dx[i]+x,b=dy[i]+y;
            if(a<0||a>=m||b<0||b>=n) continue;
            if(g[a][b]==2||g[a][b]==0) continue;
            dfs(a,b,g);
        }
    }

    public int bfs(int[][]g)
    {
        Queue<int[]> q=new LinkedList<>();
        for(int i=0;i<m;i++) 
            for(int j=0;j<n;j++) dist[i][j]=-1;

        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++) 
                if(g[i][j]==1) 
                {
                    q.offer(new int[] {i,j});
                    dist[i][j]=0;
                }
        while(!q.isEmpty())
        {
            int[] t=q.poll();
            int x=t[0],y=t[1];
            for(int i=0;i<4;i++)
            {
                int a=x+dx[i],b=y+dy[i];
                if(a<0||a>=m||b<0||b>=n) continue;
                if(dist[a][b]!=-1) continue;
                dist[a][b]=dist[x][y]+1;
                q.offer(new int[] {a,b});
                if(g[a][b]==2) return dist[a][b];
            }
        }
        return -1;
    }
}

862. 和至少为 K 的最短子数组 - 困难 - 双向单调队列+前缀和

class Solution {
    public int shortestSubarray(int[] nums, int k) {
        int n=nums.length;
        long[] sum=new long[n+1];
        for(int i=0;i<n;i++) sum[i+1]=sum[i]+nums[i]; // 计算前缀和
        Deque<Integer> q=new ArrayDeque<>();
        int ans=n+1;//ans记录满足要求的最小子串长度
        
        for(int i=0;i<=n;i++) 
        {
            while(!q.isEmpty()&&sum[i]-sum[q.peek()]>=k)
                ans=Math.min(ans,i-q.poll()); //当满足X-sum[队头]≥k 此时的ans就是最优解了
                //有最优解就可以扔掉队头了 因为后面再满足该条件 ans肯定比现在要大
 
            //维护前缀和单调递增队列
            while(!q.isEmpty()&&sum[i]<=sum[q.peekLast()])
                q.pollLast();
            
            q.offer(i);
        }
        return ans>n? -1:ans;
    }
}

1822. 数组元素积的符号 - 简单ac

class Solution {
    public int arraySign(int[] nums) {
        int sum=0;
        for(int x:nums)
        {
            if(x==0) return 0;
            if(x<0) sum++;
        }
        if(sum%2==1) return -1;
        return 1;
    }
}

907. 子数组的最小值之和 - 中等 - dp+单调栈

class Solution {
    //动态规划 dp[i]:a[i] 为右边界的min总和  
    public int sumSubarrayMins(int[] arr) 
    {
        int len=arr.length;
        int res=0;
        int mod=1000000007;
        int[] dp= new int[len];
        dp[0]=arr[0];
        Deque<Integer> st=new LinkedList<>();
        for(int i=0; i<len;i++)
        {
            while(!st.isEmpty()&&arr[st.peek()]>arr[i]) st.pop();//保证单调递增 找离它最近的比它小的值
            if(!st.isEmpty())
            {
                int j=st.peek(); 
                dp[i]=dp[j]+(i - j)*arr[i]; //j+1~i这一段以a[i]为最小值 0~j这一段以a[j]为最小值
            }else
                dp[i]=(i + 1)*arr[i]; //以a[i]为右边界的子数组都是a[i]为最小值

            res=(res+dp[i])%mod;//累加dp得到结果
            st.push(i);
        }
        return res;
    }
}

1773. 统计匹配检索规则的物品数量 - 简单 - 字符串模拟

items = ["phone","blue","pixel"]

             ["computer","silver","lenovo"]

             ["phone","gold","iphone"]

ruleKey = "color", ruleValue = "silver"

                     ↓                              ↓

                  idx=1               如果x.get(idx)==ruleValue       则res++

class Solution {
    public int countMatches(List<List<String>> items, String ruleKey, String ruleValue) {
        int idx= ruleKey.equals("type")? 0:ruleKey.equals("color")? 1:2;
        int res=0;
        for(List<String> x:items) 
            if(x.get(idx).equals(ruleValue)) res++;
        return res;
    }
}

784. 字母大小写全排列 - 中等 - 全排列dfs

class Solution {
    List<String> res=new ArrayList<>();
    public List<String> letterCasePermutation(String s) {
        char[] ch=s.toCharArray();
        dfs(ch,0);
        return res;
    }

    public void dfs(char[] ch,int idx)
    {
        res.add(new String(ch));
        for(int i=idx;i<ch.length;i++)
            if(!Character.isDigit(ch[i]))
            {
                char t=ch[i];
                ch[i]^=' ';//大小写转换
                dfs(ch,i+1);
                ch[i]=t; //还原现场
            }
    }
}

481. 神奇字符串 - 中等 - 字符串+双指针+构造

class Solution {
    public int magicalString(int n) {
        char[] s=new char[n+2]; //因为最后一次构造可能会填2个数
        s[0]=1;s[1]=s[2]=2;
        char c=2;
        for(int i=2,j=3;j<n;i++) //i负责看下一组数要填几个 j负责填充后面的组数
        {
            c=(char)(i%2+1); //实现1 2的互相转化
            s[j++]=c;
            if(s[i]==2) s[j++]=c;
        }
        int res=0;
        for(int i=0;i<n;i++) 
            if(s[i]==1) res++;
        return res;
    }
}

1662. 检查两个字符串数组是否相等 - 简单ac - 字符串模拟

class Solution {
    public boolean arrayStringsAreEqual(String[] s1, String[] s2) {
        StringBuilder ss1=new StringBuilder();
        StringBuilder ss2=new StringBuilder();
        for(String x:s1) ss1.append(x);
        for(String x:s2) ss2.append(x);
        String a=ss1.toString();
        String b=ss2.toString();
        return a.equals(b);
    }
}

1620. 网络信号最好的坐标 - 中等 - 模拟

class Solution {
    public int[] bestCoordinate(int[][] t, int radius) {
        int[] res={0,0};
        int maxx=0;
        for(int i=0;i<=50;i++) //因为坐标是从小到大枚举的 所以输出的肯定是最小的字典序坐标
            for(int j=0;j<=50;j++)
            {
                int q=0;
                for(int[] x:t) //枚举坐标轴上每个点跟这些信号塔的距离
                {
                    double s=Math.sqrt(Math.pow(i-x[0],2)+Math.pow(j-x[1],2));
                    if(s<=radius) q+=x[2]/(1+s);
                }
                if(q>maxx)
                {
                    maxx=q;
                    res[0]=i;
                    res[1]=j;
                }
            }
        return res;   
    }
}

1668. 最大重复子字符串 - 简单 - 字符串模拟

class Solution {
    public int maxRepeating(String s, String word) {
        String t=word;
        int cnt=0;
        while(s.contains(word))
        {
            word+=t;
            cnt++;
        }
        return cnt;
    }
}

754. 到达终点数字 - 中等 -数学思维

第一点:target正负情况是一样的,所以统一把target转化为正数

  • 我们的策略就是一直向右走,直到走到的位置超过target,此时的idx=1+2+……+k>=target
  • 此时超出的距离为over = idx - target
  • 所以我们将之前走过的某一步x反向,使idx' = 1+2+……-x+……+k = target = idx - over
  • 某一步反向也就是在idx基础上-2x,即idx' = idx-2x(因为idx是+x,而idx'是-x,两者相差2x)
  • 所以over = 2x = idx - target,所以idx - target必须是偶数
  • 所以我们只需要找到第一个使 idx = 1 + 2 + ... + k >= target 且 idx - target 为偶数的 k 即为答案
class Solution {
    public int reachNumber(int target) {

        target=Math.abs(target);
        int cnt=0,idx=0;
        while(idx<target||(idx-target)%2==1) //idx<target能一次性向右走到
            idx+=++cnt;
        return cnt;
    }
}

1106. 解析布尔表达式 - 困难 - 栈

class Solution {
    public boolean parseBoolExpr(String s) 
    {
        Deque<Character> st=new ArrayDeque<>();
        for(int i=0;i<s.length();i++)
        {
            char c=s.charAt(i);
            if(c==',')  continue;
            else if(c!=')') st.push(c);
            else
            {
                int f=0,t=0;
                while(st.peek()!='(')
                {
                    if(st.pop()=='t') t++;
                    else f++;
                }
                st.pop(); //把(弹出
                char x=st.pop(); //接收运算符
                switch(x)
                {
                    case '&': st.push(f>0?'f':'t');break;
                    case '|': st.push(t>0?'t':'f');break;
                    case '!': st.push(f==1?'t':'f');break;
                }
            }
        }
        return st.pop()=='t';
    }
}

1678. 设计 Goal 解析器 - 简单ac

class Solution {
    public String interpret(String s) {
        String res="";
        for(int i=0;i<s.length();i++)
        {
            if(s.charAt(i)=='G') res+="G";
            if(s.charAt(i)=='('&&s.charAt(i+1)==')') 
            {
                res+="o";
                i++;
            }
            if(s.charAt(i)=='('&&s.charAt(i+1)=='a')
            {
                res+="al";
                i+=3;
            }
        }
        return res;
    }
}

816. 模糊坐标 - 中等 - 字符串+枚举+指针分割

class Solution {
    public List<String> ambiguousCoordinates(String s) {
        int n=s.length()-2; //去掉括号的长度
        List<String> res=new ArrayList<>();
        s=s.substring(1,s.length()-1);
        for(int i=1;i<n;i++)
        {
            List<String> l=get(s.substring(0,i));
            List<String> r=get(s.substring(i));
            for(String a:l)
                for(String b:r)
                    res.add("("+a+", "+b+")");
        }
        return res;
    }

    public List<String> get(String s)
    {
        List<String> ans=new ArrayList<>();
        if(s.charAt(0)!='0'||"0".equals(s)) //如果该串没有前导零 或 该串只是个0 则直接添加到结果
            ans.add(s);
        for(int i=1;i<s.length();i++) //然后用小数点开始分割
        {
            if((i!=1&&s.charAt(0)=='0')||s.charAt(s.length()-1)=='0') 
                continue; //如果有前缀0 或 最后有0缀余则直接跳过
            //比如:0 0 2 3 当i=2时 分割为00.23 也就是小数点之前只允许有一个0 当小数点向后移时,若第一位还是0 说明是前缀0
            ans.add(s.substring(0,i)+"."+s.substring(i));
        }
        return ans;
    }
}

1684. 统计一致字符串的数目 - 简单ac

class Solution {
    public int countConsistentStrings(String s, String[] words) {
        Set<Character> st=new HashSet<>();
        for(int i=0;i<s.length();i++) st.add(s.charAt(i));
        int cnt=words.length;
        for(int i=0;i<words.length;i++)
        {
            for(int j=0;j<words[i].length();j++)
                if(!st.contains(words[i].charAt(j)))
                {   
                    cnt--;
                    break;
                }
        }
        return cnt;
    }
}

764. 最大加号标志 - 中等 - 暴力

思路:

从某个点开始上下左右拓展 用ans更新每个点能达到的最大阶数

class Solution {
    public int orderOfLargestPlusSign(int n, int[][] min) 
    {
        int ans=0;
        int[][] g=new int[n][n];
        for(int i=0;i<min.length;i++) g[min[i][0]][min[i][1]]=1;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++) ans=Math.max(ans,dfs(i,j,n,g));
        return ans;
    }

    public int dfs(int x,int y,int n,int[][]g)
    {
        int res=0;
        if(g[x][y]==1) return 0;
        while(true)
        {
            if(x-res<0||g[x-res][y]==1||x+res==n||g[x+res][y]==1||y-res<0||g[x][y-res]==1||y+res==n||g[x][y+res]==1) break;
            res++;
        }
        return res;
    }
}

864. 获取所有钥匙的最短路径 - 困难 - bfs+状态压缩+位运算+最短路

class Solution {

    static int N=30,K=6,INF=0x3f3f3f3f;
    static int[][] dirs=new int[][]{{1,0},{-1,0},{0,-1},{0,1}};
    //x y代表坐标,s代表当前钥匙状态 pos表示当前步的最短路
    static int[][][] pos=new int[N][N][1<<K];

    public int shortestPathAllKeys(String[] g) 
    {   
        Deque<int[]> q=new ArrayDeque<>();
        int m=g.length,n=g[0].length();
        int key=0;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            {
                Arrays.fill(pos[i][j],INF); //初始化每个格最短距离为无穷大
                char ch=g[i].charAt(j);
                if(ch=='@')
                {
                    q.offerLast(new int[]{i,j,0});
                    pos[i][j][0]=0;
                }else if(ch>='a'&&ch<='z') key++;
            }

        while(!q.isEmpty())
        {
            int[] t=q.pollFirst();
            int x=t[0],y=t[1],state=t[2];
            int step=pos[x][y][state];
            for(int[] dir:dirs)
            {
                int nx=x+dir[0],ny=y+dir[1];
                if(nx<0||nx>=m||ny<0||ny>=n) continue;
                char c=g[nx].charAt(ny);
                if(c=='#') continue;
                if((c>='A'&&c<='Z')&&(state>>(c-'A')&1)==0) continue; //如果遇到锁但是没有钥匙 跳过

                int next=state; //因为state在for循环外定义的,所以不能直接更改,需要先定义变量接收
                if(c>='a'&&c<='z') 
                    next|=1<<(c-'a'); //如果是钥匙 则更新状态

                if(next==(1<<key)-1) return step+1; //如果钥匙状态全为1 说明再走一步钥匙搜集完毕
                if(step+1>=pos[nx][ny][next]) continue; //如果之前有更短的走法则跳过不走

                pos[nx][ny][next]=step+1;
                q.offerLast(new int[]{nx,ny,next});
            }
        }
        return -1;

    }
}

1704. 判断字符串的两半是否相似 - 简单ac

class Solution {
    public boolean halvesAreAlike(String s) {
        int len=s.length();
        String a=s.substring(0,len/2),b=s.substring(len/2);
        String h="aeiouAEIOU";
        int cnta=0,cntb=0;
        for(int i=0;i<a.length();i++) 
            if(h.indexOf(a.charAt(i))>=0) cnta++;
        for(int i=0;i<b.length();i++)
            if(h.indexOf(b.charAt(i))>=0) cntb++;
        return cnta==cntb;
    }
}

791. 自定义字符串排序 - 中等 - 模拟

class Solution {
    public String customSortString(String order, String s) {
        StringBuilder res=new StringBuilder();
        int[] cnt=new int[26];
        for(char c:s.toCharArray()) cnt[c-'a']++;
        for(char c:order.toCharArray()) 
            while(cnt[c-'a']-->0) res.append(c);
        for(char c:s.toCharArray()) if(cnt[c-'a']-->0) res.append(c);
        return res.toString();
    }
}

1710. 卡车上的最大单元数  - 简单ac - 自定义排序

class Solution {
    public int maximumUnits(int[][] box, int truckSize) {
        Arrays.sort(box,(a,b)->b[1]-a[1]); //按箱子装载数从大到小排序
        int sum=0;
        for(int i=0;i<box.length;i++) 
            if(truckSize>=box[i][0])
            {
                sum+=box[i][0]*box[i][1];
                truckSize-=box[i][0];
            }else
            {
                sum+=truckSize*box[i][1];
                break;
            } 
        return sum;
    }
}

1732. 找到最高海拔 - 简单ac

class Solution {
    public int largestAltitude(int[] gain) {
        int[] a=new int[gain.length+1];
        a[0]=0;
        int cnt=1,sum=0;
        for(int i=0;i<gain.length;i++)
        {
            sum+=gain[i];
            if(i==0) a[cnt++]=gain[i];
            else a[cnt++]=sum;
        }
        int maxx=a[0];
        for(int i=1;i<a.length;i++) maxx=Math.max(maxx,a[i]);
        return maxx;
    }
}

799. 香槟塔  - 中等 - 模拟

class Solution {
    public double champagneTower(int poured, int query_row, int query_glass) 
    {
        double[][] cup=new double[101][101];
        cup[0][0]=poured; //先把所有的香槟倒到第一个杯子里

        for(int i=0;i<=query_row;i++)
            for(int j=0;j<=i;j++)
                if(cup[i][j]>1) //如果这个杯子满了
                {
                    double half=(cup[i][j]-1)/2.0; //把这个杯子装满之后 其他的减半流入下层
                    cup[i][j]=1;
                    cup[i+1][j]+=half;
                    cup[i+1][j+1]+=half;
                }
        return cup[query_row][query_glass];
    }
}



1742. 盒子中小球的最大数量 - 简单ac

class Solution {
    public int countBalls(int lowLimit, int highLimit) {
        int[] cnt=new int[50];
        int maxx=0;
        for(int i=lowLimit;i<=highLimit;i++)
        {
            int sum=0;
            int t=i;
            while(t!=0)
            {
                sum+=t%10;
                t/=10;
            }
            cnt[sum]++;
        }
        for(int i=0;i<=45;i++) maxx=Math.max(maxx,cnt[i]);
        return maxx;
    }
}

809. 情感丰富的文字 - 中等 - 双指针计数

class Solution {
    public int expressiveWords(String s, String[] words) {
        int res=0;
        for(String x:words)
            if(check(s,x)) res++;
        return res;
    }

    public boolean check(String s,String x)
    {
        int i=0,j=0;
        while(i<s.length()&&j<x.length())
        {
            if(s.charAt(i)!=x.charAt(j)) return false;
            char ch=s.charAt(i);
            int cnti=0,cntj=0;
            while(i<s.length()&&s.charAt(i)==ch) 
            {
                cnti++;
                i++;
            }
            while(j<x.length()&&x.charAt(j)==ch)
            {
                cntj++;
                j++;
            }
            if(cnti==cntj) continue;
            if(cnti<cntj) return false;
            if(cnti!=cntj&&cnti<3) return false;
        }
        return i==s.length()&&j==x.length();
    }
}

1752. 检查数组是否经排序和轮转得到 -简单ac - 自写暴力法

class Solution {
    public boolean check(int[] nums) {
        int n=nums.length;
        int[] a=new int[n];
        for(int i=0;i<n;i++) a[i]=nums[i];
        Arrays.sort(nums);
        for(int i=0;i<=n-1;i++)
        {
            int cnt=0;
            for(int j=0;j<n;j++)
            {
                if(nums[j]==a[(j+i)%n]) cnt++;
            }
            if(cnt==n) return true;
        }
        return false;
    }
}

1779. 找到最近的有相同 X 或 Y 坐标的点 - 简单ac

class Solution {
public:
    int nearestValidPoint(int x, int y, vector<vector<int>>& points) {
        int minx=0x3f3f3f3f,idx=-1;
        for(int i=0;i<points.size();i++)
            if(points[i][0]==x||points[i][1]==y)
            {
                int d=abs(points[i][0]-x)+abs(points[i][1]-y);
                if(d<minx) minx=d,idx=i;
            }
        return idx;
    }
};

1796. 字符串中第二大的数字 - 简单ac

class Solution {
public:
    int secondHighest(string s) {
        set<int>st;
        for(int i=0;i<s.size();i++)
            if(isdigit(s[i]))
            {
                int c=s[i]-'0';
                st.insert(c);
            } 
        if(st.size()<2) return -1;
        st.erase(*st.rbegin());
        return *st.rbegin();
    }
};
class Solution {
public:
    int secondHighest(string s) {
        set<int>st;
        for(int i=0;i<s.size();i++)
            if(isdigit(s[i]))
            {
                int c=s[i]-'0';
                st.insert(c);
            } 
        for(auto x:st) cout<<x<<' ';
        if(st.size()>=2) 
        {
            auto it=st.end();
            --it;
            return *(--it);
        }
        return -1;
    }
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值