LeetCode Top100 Liked 题单(序号1~17)

news2024/11/15 17:26:07

01Two Sum - LeetCode

我自己写的代码【193ms】

因为不知道怎么加cmp函数,就只能pair的first设为值了,但其实这也是瞎做,应该也是O(n²)吧

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        pair<int,int>pa[10004];int n=0;
        for(auto i:nums){
            pa[n].first=i;pa[n].second=n;n=n+1;
        }
        sort(pa,pa+n);
        int j=0,i=1;
        while(j<n){
            if(pa[i].first+pa[j].first<target){
                if(i!=n-1)i++;
                else {j++;i=j+1;}
            }
            else if(pa[i].first+pa[j].first>target){
                j++;i=j+1;
            }
            else return {pa[i].second,pa[j].second};
        }  
        return {-1,-1};
    }
};

O(n²)代码【319ms】

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

        return {-1,-1};
    }
};

O(nlogn)代码【16ms】

我想到了排序,也想到了应该双指针,但没想到应该左指针在最左,右指针在最优

如果总和大于target,大的变小,如果总和小于target,小的变大。

class Solution {
public:
    
    vector<int> twoSum(vector<int>& nums, int target) {
        pair<int,int>pa[10004];int n=0;
        for(auto i:nums){
            pa[n].first=i;pa[n].second=n;n=n+1;
        }
        sort(pa,pa+n);
        int j=0, i=n-1;
        while(j<i){
            int sum = pa[j].first+pa[i].first;
            if(sum==target) return {pa[j].second, pa[i].second};
            else if(sum>target) i--;
            else j++;
        }
        return {-1,-1};
    }
};

O(n)代码【4ms】

用了Hash。原理是加入一个值,如果map里面有对应的值就输出各自的序号,没有就保存序号。蓝桥杯有一道题好像就是这样做的

class Solution {
public:
    
    vector<int> twoSum(vector<int>& nums, int target) {
        int n = nums.size();
        unordered_map<int,int> mp;
        for(int i=0;i<n;i++){
            if(mp.count(target-nums[i])) return {i,mp[target-nums[i]]};
            mp[nums[i]] = i;
        }
        return {-1,-1};
    }
};

02Add Two Numbers - LeetCode

一开始看错了,以为最右边是个位,看了一些答案才发现是最左边是个位

首先先创建一个头节点,之后有一个移动指针p->next=new ListNode(sum%10);

一直到链表遍历完,进位(carry)结束

最后返回链表head->next

我的代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* head=new ListNode();
        ListNode* p=head;
        int carry=0;
        while(l1!=NULL||l2!=NULL||carry){
            int sum=0;
            if(l1!=NULL){
                sum+=l1->val;
                l1=l1->next;
            }
            if(l2!=NULL){
                sum+=l2->val;
                l2=l2->next;
            }
            sum+=carry;
            carry=sum/10;
            p->next=new ListNode(sum%10);
            p=p->next;      //p指向下一个结点
        }
        return head->next;
    }
};

递归做法

class Solution {
public:
    ListNode *helper(ListNode *l1,ListNode *l2,int carry){
        if(!l1 && !l2){
            if(carry) return new ListNode(carry);
            else return NULL;
        }
        int val=(l1?l1->val:0)+(l2?l2->val:0)+carry;
        ListNode *res=new ListNode(val%10);
        res->next=helper((l1?l1->next:NULL),(l2?l2->next:NULL),val/10);
        return res;
    }
    ListNode *addTwoNumbers(ListNode *l1,ListNode *l2){
        return helper(l1,l2,0);
    }
};

03 Longest Substring Without Repeating Characters

有思路但不会写

我的思路

时间复杂度为n,就是直接扫一遍,每次扫到一个字符

        如果vis为0,vis[i]设为1

        如果扫到的vis已经为1,从头pop_front(),直到vis[i]为0,比较ans和max的大小,选择保留

之后,将扫到的字符加入ans中

困难

我发现string容器没有pop_front,而且每一次比较ans和max的大小,选择保留时都要重新遍历一遍,时间复杂度其实挺大的

答案思路

答案也用了vis,不过直接先把string存起来,记录pair下表

时隔几个星期后

之前的思路已经忘光光了,重新整理了思路,用vis记录string的下标,st的子串的左端点,string从1开始计数

若vis[s[i]]为真,那么将st到vis[s[i]]之间的字符的vis清零,st更新为vis[s[i]]+1,将vis[s[i]]更新为i;若vis[s[i]]为假,代表没遇到过这个字符,直接记录位置;

最后字符串循环一次后,记得再更新一次max的大小!!

另外初始化的时候,直接空字符串输出0!!

代码【11ms】

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s=="")return 0;
        if(s=="")return 0;
        int vis[300]={0};pair<int,int>maxx;int st=1;maxx.first=1; maxx.second=1;
        s="!"+s;
        vis[s[st]]=st;
        for(int i=2;i<s.size();i++){
            if(vis[s[i]]){
                if((i-st)>(maxx.second-maxx.first)){
                    maxx.first=st; maxx.second=i;
                }
                while(st<=vis[s[i]]){vis[s[st]]=0;st++;}//将st更新到重复出现的位置的后面
            }
            vis[s[i]]=i;//如果没有,记录位置;有就更新位置
        }
        if((s.size()-st)>(maxx.second-maxx.first)){
            maxx.first=st; maxx.second=s.size();
       }
        return maxx.second-maxx.first;
    }  
};

4. Median of Two Sorted Arrays

两个已排好序的数组 找中位数 数组从0开始计数

算法课上学过O(log(mn))的算法,但是忘记了,只会O(m+n)的合并后直接中位数了

代码【43ms Beats 62.01%】O(m+n)

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        vector<int>use;
        int len1=nums1.size(),len2=nums2.size();
        int i=0,j=0;
        for(;i<len1&&j<len2;){
            if(nums1[i]<nums2[j]){
                use.push_back(nums1[i]);i++;
            }
            else {
                use.push_back(nums2[j]);j++;
            }
        }
        while(i<len1){use.push_back(nums1[i]);i++;}
        while(j<len2){use.push_back(nums2[j]);j++;}
        int len=use.size();
        if(len%2==1){return use[len/2];}
        return (use[len/2]+use[len/2-1])/2.0;
    }
};

看了解析后:

简述:用二分查找的思想做这道题。如果要更小的,把最大的那部分给删了;如果要更大的,把最小的那部分给删了

设A数组和B数组的中位数为AM和AM,其位置是AI和BI,为了找位置为K的数:

如果AI+BI小于K,说明AI和BI的位置小了,要大一点

       若AV小于BV,那么把【Astart,AI】的部分删掉,确保不会删掉第K位数;反之亦然。

如果AI+BI大于等于K,说明 Astart到AI 和 Bstart到BI (共AI+BI+2个数)中有位置为K的数;

        若AV大于BV,那么把【AI,Aend】的部分删掉,确保不会删掉第K位数;反之亦然。

最后A或者B的Start>End,结束;若BStart>BEnd,最后返回A【k-BStart】,反之亦然

代码【35ms Beats 86.96%】 O(log(m*n))

注意数组的范围是【0, n.size()-1】!!!

class Solution {
public:
    double findMedianSortedArrays(vector<int>& n, vector<int>& m) {
        int num=int(n.size())+int(m.size());
        if(num%2)
            return q(n,m,num/2,0,n.size()-1,0,m.size()-1);
        return (q(n,m,num/2,0,n.size()-1,0,m.size()-1)+q(n,m,num/2-1,0,n.size()-1,0,m.size()-1))/2.0;
    }
     double q(vector<int>& a,vector<int>& b,int k,int Astart,int Aend,int Bstart,int Bend){
          if(Astart>Aend)return b[k-Astart];
          if(Bstart>Bend)return a[k-Bstart];
          int AIndex=(Astart+Aend)/2,BIndex=(Bstart+Bend)/2;
          int aV=a[AIndex],bV=b[BIndex];
          if(AIndex+BIndex<k){//删除小的部分
               if(aV>bV)
                    return q(a,b,k,Astart,Aend,BIndex+1,Bend);
               else 
                    return q(a,b,k,AIndex+1,Aend,Bstart,Bend);
          }
          else{//删除大的部分
               if(aV>bV)
                    return q(a,b,k,Astart,AIndex-1,Bstart,Bend);
               else 
                    return q(a,b,k,Astart,Aend,Bstart,BIndex-1);
          }
     return -1;
     }
};

还有一个做法是O(log⁡(min⁡(m,n))),但是我没有看懂,在实际运行的时候,是45ms,就很怪

!没看懂的代码

class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        if (nums1.size() > nums2.size()) {
            return findMedianSortedArrays(nums2, nums1);
        }
        
        int m = nums1.size(), n = nums2.size();
        int left = 0, right = m;
        
        while (left <= right) {
            int partitionA = (left + right) / 2;
            int partitionB = (m + n + 1) / 2 - partitionA;
            
            int maxLeftA = (partitionA == 0) ? INT_MIN : nums1[partitionA - 1];
            int minRightA = (partitionA == m) ? INT_MAX : nums1[partitionA];
            int maxLeftB = (partitionB == 0) ? INT_MIN : nums2[partitionB - 1];
            int minRightB = (partitionB == n) ? INT_MAX : nums2[partitionB];
            
            if (maxLeftA <= minRightB && maxLeftB <= minRightA) {
                if ((m + n) % 2 == 0) {
                    return (max(maxLeftA, maxLeftB) + min(minRightA, minRightB)) / 2.0;
                } else {
                    return max(maxLeftA, maxLeftB);
                }
            } else if (maxLeftA > minRightB) {
                right = partitionA - 1;
            } else {
                left = partitionA + 1;
            }
        }
        
        return 0.0;
    }
};

5. Longest Palindromic Substring

题意:给一个字符串,找回文串

我知道这是马拉车问题,但是我不记得马拉车的代码怎么写了;好像哈希也可以做这种题目,但是我能想到的哈希也是O(n^2)

我的思路

首先设回文串是单数,遍历一遍字符串,接着设回文串是双数,遍历一遍字符串,时间复杂度是O(n^2)

class Solution {
public:
    string longestPalindrome(string s) {
        string st="";
        for(int i=0;i<s.size();i++){
            int r=0;
            for(r=0;r<=i;r++){
                if(s[i-r]!=s[i+r])break;
            }
            r--;
            if((int)st.size()<2*r+1){st="";for(int d=i-r,co=0;d<=i+r;d++)st+=s[d];}
            r=0;
            for(r=0;r<=i+1;r++){
                if(s[i-r+1]!=s[i+r])break;
            }
            r--;
            if((int)st.size()<2*r){st="";for(int d=i-r+1,co=0;d<=i+r;d++)st+=s[d];}
        }
        return st;
    }
};

查解析的时候看到又说区间动态规划做这道题的,动态规划已经完全不会了qwq

不过动态规划和我这个方法的时间复杂度居然差不多 哈哈

我看懂了!

首先每个字母是一个回文串,所以所有dp[0][i]=True,之后一个个排,差不多就是这意思,看代码肯定能看懂

代码【180ms】区间dp O(n^2)

class Solution {
public:
    string longestPalindrome(string s) {
        int n=s.size();
        string ans="";ans+=s[0];
        bool dp[1005][1005]={0};//字母最后一个的序号 里回文串长度(不包含最后一个字母的长度)
        for(int i=0;i<1005;i++)dp[i][0]=1;
        for(int i=1;i<n;i++){
            for(int j=i-1;j>=0;j--){
                if(s[i]==s[j]){
                    if(i-j==1||dp[i-1][i-j-2]){
                        dp[i][i-j]=1;
                        if((int)ans.size()<i-j+1){
                            ans="";for(int d=j;d<=i;d++)ans+=s[d];}
                    }
                }
            }
        }
        return ans;
    }
};

然后看到同样是O(n^2)的双指针法,但是不理解为什么能快那么多

同样是看了代码就知道怎么做的了

代码 【9ms Beats 95.99%】双指针法 

直接黏贴了别人的代码

class Solution {
public:
    string longestPalindrome(string s) {
        int lenLP=1;
        int startLP=0;
        int n=s.length();
        for(int i=0;i<n;i++){
            int right=i; // initialize right to current index
            while(right<n && s[i]==s[right]) right++; // while equal characters increment right
            int left=i-1; // initialize left to current index - 1
            while(left>=0 && right<n && s[left]==s[right]){
                left--;
                right++;
            }
            int len=(right-1)-(left+1)+1;
            if(len>lenLP){
                lenLP=len;
                startLP=left+1;
            }
        }
        return s.substr(startLP,lenLP);
    }
};

Manacher算法

算法思想

首先在首尾和每个数字之间添加”#“,例如”aofs“改成”“#a#o#f#s#”,这样解决了奇偶不同的问题,即字符串永远都是奇数,同时第0位,随便加上一个符号

p表示包括当前字符的 加入#后的 回文串半径,例如

# a # a # c # a # b # d # k # a # c # a # a #

1 2 3 2 1 4 1 2 1 2 1 2 1 2 1 2 1 4 1 2 3 2 1

pos和maxlen表示答案的中心和长度

id和mx表示最右边的回文串的中心和端点,注意:mx不包含在回文串中

遍历字符串 t 时,如果此时在最右回文串的外面(或者i=1时,mx=0),即 i>mx,那么p[i]=1

若 i 在最右边的已知回文串区域的右端点里面,说明这个回文串左边镜像字符 2*id-i 已经求过p[i]了
如果 p[2*id-i]+i 大于mx,即p[2*id-i]大于mx-i,就暂定p[i]=mx-i,因为超出回文串了
如果p[2*id-i]+i 小于mx,即p[2*id-i]小于mx-i,因为还在回文串里面,所以p[i]=p[2*id-i]

在 t[i+p[i]] == t[i-p[i]] 的基础上,向外扩展、更新p[i]

如果出现了新的最右字符串,那么更新id和mx

代码【10ms Beats 95.49%】Manacher

居然和上面的双指针时间差不多 哈哈

class Solution {
public:
string longestPalindrome(string s) {
        string t = "$#";
        for(auto i : s){
            t += i;
            t += "#";
        }
        vector<int>p(t.size(),1);//包括当前字符的 加入#后的 回文串半径
        int pos = 0;
        int maxlen = 0;
        int id = 0;
        int mx = 0;
        for(int i=1;i<t.size();i++){//遍历字符串
            p[i] = i<mx?min(p[2*id-i],mx-i):1;
//i=0 或 i已经比最右边的已知回文串区域的右端点还要右, p[i]=1;
//若i在最右边的已知回文串区域的右端点里面,说明这个回文串左边镜像字符2*id-i已经求过p[i]了
//如果 p[2*id-i]+i 大于mx,即p[2*id-i]大于mx-i,就暂定p[i]=mx-i,因为超出回文串了
//如果p[2*id-i]+i 小于mx,即p[2*id-i]小于mx-i,因为还在回文串里面,所以p[i]=p[2*id-i]
            while(t[i+p[i]] == t[i-p[i]]){
//当前位置i,已经知道当前的位置的p[i](p[i]是包括自己的)
                p[i]++;//向外拓展来更新p[i]
            }
            if(i+p[i]>mx){//mx是最右边的已知回文串区域的右端点,不在回文串里面的第一个数字
                mx = i+p[i];
                id = i;//最右边的已知回文串中心
            }
            //记录最终的答案
            if(p[i]>maxlen){
                maxlen = p[i];
                pos = i;
            }
        }
        //(pos - maxlen)/2 长度
        return s.substr( (pos - maxlen)/2,maxlen-1 );
    }

};

11. Container With Most Water

题意:求min(h[l] , h[r])*(r - l)最大

我的思路

双循环,O(n^2),但n=1e5 会超时,不会做不会做

双指针解析

参考:6.container-with-most-water(装最多水的容器

以序列最外面两条边形成的乘积为起始面积,找出两条边中较小的一条,索引加一(i++),找出一条更大的边来代替较小的边,以使得整个容器最大(可以看参考链接的图,更易于理解)

代码 自己写的 111ms Beats 35.18%

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

 上述代码中还有可以优化的地方,因为当 l 或 r 更新时,一定要找到更大的h[ l ]或者h[ r ],否则对答案无影响

代码修改后 92ms Beats 92.74%

class Solution {
public:
    int maxArea(vector<int>& h) {
        int l=0,r=h.size()-1;
        int maxx=0,minh=9999999;
        while(l<r){
            minh=min(h[l],h[r]);
            maxx=max(maxx,minh*(r-l));
            while(l<r && h[r]<=minh)r--;
            while(l<r && h[l]<=minh)l++;
        }
        return maxx;
    }
};

为什么可以连续的h[r]<=minh和h[l]<=minh?例如【8,88,8】答案为16,就算右边动了,变成了【8,16】,最小的高还是8,底宽还变小了,所以在底宽变小的前提下,一定要将minh提高才可以

13. Roman to Integer

题意:给一串字符串,写出代表的罗马数字

我的思路

普通的模拟

改成if…else……可以从7ms进化成3ms

代码 3ms Beats 97.3% 模拟

class Solution {
public:
    int romanToInt(string s) {
        int ans=0;
        for(int i=0;i<s.size();i++){
            if(s[i]=='I'&&i+1<s.size()){
                if(s[i+1]=='V'){ans+=4;i++;continue;}
                else if(s[i+1]=='X'){ans+=9;i++;continue;}
            }
            else if(s[i]=='X'&&i+1<s.size()){
                if(s[i+1]=='L'){ans+=40;i++;continue;}
                else if(s[i+1]=='C'){ans+=90;i++;continue;}
            }
            else if(s[i]=='C'&&i+1<s.size()){
                if(s[i+1]=='D'){ans+=400;i++;continue;}
                else if(s[i+1]=='M'){ans+=900;i++;continue;}
            }
            if(s[i]=='I')ans+=1;
            else if(s[i]=='V')ans+=5;
            else if(s[i]=='X')ans+=10;
            else if(s[i]=='L')ans+=50;
            else if(s[i]=='C')ans+=100;
            else if(s[i]=='D')ans+=500;
            else if(s[i]=='M')ans+=1000;
        }
        return ans;
    }
};

14. Longest Common Prefix

题意:给出前缀组Str,找到最长的字符串前缀

我的思路

用map把所有Str中的string的所有前缀都收集了,在收集过程中记录下最长的前缀

代码 232ms Beats 5.31%

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        map <string,int> mp;
        int mx=0;string a="";string tmp="";
        for(int i=0;i<strs.size();i++){
            tmp="";
            for(int j=0;j<strs[i].size();j++){
                tmp+=strs[i][j];
                mp[tmp]+=1;
                cout<<tmp<<" "<<mp[tmp]<<endl;
                if(mp[tmp]==(int)strs.size()&&(int)tmp.size()>mx){
                    mx=(int)tmp.size();a=tmp;
                }
            }
        }
        return a;
    }
};

标答思路

看公共前缀就把字符串组排序,看最后和最前的公共字符前缀即可

代码  3ms Beats 89.36% 逻辑构造题

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
       string tmp="";
       sort(strs.begin(),strs.end());
       int first=0,last=(int)strs.size()-1;
       for(int i=0;i<min(strs[first].size(),strs[last].size());i++){
           if(strs[first][i]==strs[last][i])tmp+=strs[first][i];
           else break;
       }
       return tmp;
    }
};

15. 3Sum

题意:给定一串数组,输出三个数,使得三个数的和为0

我的思路

O(n^2)组成pair组,存入pair的和,线性组,以后一一对照 总之全部用map实现

最后居然过了没想到的哈哈哈哈哈

代码 2999ms Beats 5.00%

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<pair<int,int> > pr[200005];int n=nums.size();map<int,int> a;
        set< vector<int>> ans;vector<vector<int>> aa;
        for(int i=0;i<n;i++){
            a[nums[i]]++;
        }
        for(auto i:a){
            for(auto j:a){
                if(i.first==j.first &&i.second<=1)continue;
                int as=i.first+j.first;
                if(as+100000<0||as+100000>200000)continue;
                pr[as+100000].push_back({i.first,j.first});
            }
        }//把所有的和都放好了
        for(auto i:a){
            int id=100000-i.first;
            if(!pr[id].empty()){//如果有对应的
                for(int j=0;j<pr[id].size();j++){//核对每一个符合的pair
                    if(i.first!=pr[id][j].first&&i.first!=pr[id][j].second
                    ||i.first==pr[id][j].first&&i.first!=pr[id][j].second&&i.second>1
                    ||i.first!=pr[id][j].first&&i.first==pr[id][j].second&&i.second>1
                    ||i.first==pr[id][j].first&&i.first==pr[id][j].second&&i.second>2
                    ){//如果三个数的序号不一样
                        vector<int> a;a.push_back(i.first);
                        a.push_back(pr[id][j].first);a.push_back(pr[id][j].second);
                        sort(a.begin(),a.end());
                        ans.insert(a);
                    }
                }
            }
        }
        for (auto q:ans){aa.push_back(q);}
        return aa;
    }
};

标答 双指针

首先将nums按大小排序,这样方便之后查找目标答案

顺序遍历nums,target就是-nums[i],设left是i+1,right是nums.size()-1,sum=nums[left] + nums[right]

如果sum<target,说明sum太小了,left向右移来增大sum;如果sum>target,说明sum太大了,left向左移来减小sum;

如果sum=target,那么刚好{nums[i], nums[left], nums[right]}加入vector中【还是排好序的】,因为适配的target的组合不止一个,所以移动left和right来跳过相同的数,之后接着查找,直到left>right停止

代码 113ms Beats 97.35% 双指针+排序

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
    vector<vector<int>> result;
    int n = nums.size();// Sort the array to use two-pointer approach
    sort(nums.begin(), nums.end());
    for (int i=0; i<n-2;++i) {
        if (i>0 && nums[i] == nums[i - 1]) {
            continue; // Skip duplicates for the first element
        }
        int target = -nums[i];
        int left = i + 1;
        int right = n - 1;
        while (left < right) {
            int sum = nums[left] + nums[right];
            if (sum == target) {
                result.push_back({nums[i], nums[left], nums[right]});
                while (left < right && nums[left] == nums[left + 1]) 
                    left++; // Skip duplicates for the second element
                left++;
                while (left < right && nums[right] == nums[right - 1])
                    right--;
                right--;    // Skip duplicates for the third element
            }
            else if (sum < target) left++;
            else right--;
        }
    }
    return result;
}
};

17. Letter Combinations of a Phone Number

我的思路

直接死算(?),用map一个个放,最后输出符合个数的

代码 5ms Beats 9.32%

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        vector<string> result; 
        vector <string> mp;
        vector<string> as={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        int start=0,end=0;
        for(int i=0;i<digits.size();i++){//输入的按钮     
            int id=(digits[i]-'0')-2;
            if(i==0){//初始化
                for(int j=0;j<as[id].size();j++) {
                    string tmp;tmp+=as[id][j];
                    mp.push_back(tmp);
                }
                start=end;end=as[id].size();
                cout<<start<<" "<<end<<" "<<endl;
                continue;
            }
            for (int i=start;i<end;i++){//增加
                for(int j=0;j<as[id].size();j++){
                    string tmp;tmp=mp[i];
                    tmp+=as[id][j];
                    mp.push_back(tmp);
                }
            }
            int st=end;end=end+(int)as[id].size()*(end-start);start=st;
        }
        for (int i=start;i<end;i++){
            result.push_back(mp[i]);
        }
        return result;
    }
};

标答 

普通的循环:用两个vector交替,另外上面代码的-2好像不太行

代码 0ms Beats 100% 循环

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        if(digits.empty()) return{};
        vector<string> as={"", "", "abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        vector<string> output={""};
        for (auto st:digits){//输入
            vector<string> temp;
            for(auto c: as[(st-'0')] ){//字母
                for(auto t:output){
                    temp.push_back(t+c);
                }
            }
            output.clear();
            output=temp;
        }
        return output;
    }
};

代码 0ms 6.27mb Beats 97.65% 递归

在主函数中,首先如果digit的长度为0,那就返回空;规定好mapping后进入递归函数

在递归函数中,跳出的条件是index大于digit的长度,ans把一次的outpu加入,退出递归;在递归中,首先是循环(表示这个按键可以是什么字母)进入递归(index+1),出递归后把这个字母弹出,进入下次循环装上下个可能的字母

class Solution {
public:
    void solve(string &digits,vector<string> &ans,string &output,int index,vector<string> &mapping)
    {
        if(index>=(int)digits.size()){
            ans.push_back(output);
            return;
        }
        int id=digits[index]-'0';
        for(int i=0;i<(int)mapping[id].size();i++){
            output.push_back(mapping[id][i]);
            solve(digits,ans,output,index+1,mapping);
            output.pop_back();
        }
    }

    vector<string> letterCombinations(string digits) {
        if(!(int)digits.size())return {};
        int index=0;vector<string> ans;
        string output="";
        vector<string> mapping={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        solve(digits,ans,output,index,mapping);
        return ans;
    }

};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/798465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【观察】智能运维的“下半场”,看云智慧如何“开新局”

毫无疑问&#xff0c;随着数字化转型的加速&#xff0c;越来越多的企业正在把数字化战略提升到一个全新的高度&#xff0c;转型的进程也正从“浅层次”的数字化走向“深层次”的数字化。 也正因此&#xff0c;过去传统的人工运维方式越来越“捉襟见肘”&#xff0c;谋求运维模…

飞桨paddlespeech语音唤醒推理C定点实现

前面的文章&#xff08;飞桨paddlespeech语音唤醒推理C浮点实现&#xff09;讲了飞桨paddlespeech语音唤醒推理的C浮点实现。但是嵌入式设备通常CPU频率低和memory小&#xff0c;在嵌入式设备上要想流畅的运行语音唤醒功能&#xff0c;通常用的是定点实现。于是我就在浮点实现&…

【redis】通过配置文件简述redis的rdb和aof

redis的持久化方式有2种&#xff0c;rdb&#xff0c;即通过快照的方式将全量数据以二进制记录在磁盘中&#xff0c;aof&#xff0c;仅追加文件&#xff0c;将增量的写命令追加在aof文件中。在恢复的时候&#xff0c;rdb要更快&#xff0c;但是会丢失一部分数据。aof丢失数据极少…

HTML快速学习

目录 一、网页元素属性 1.全局属性 2.标签 2.1其他标签 2.2表单标签 2.3图像标签 2.4列表标签 2.5表格标签 2.6文本标签 二、编码 1.字符的数字表示法 2.字符的实体表示法 三、实践一下 一、网页元素属性 1.全局属性 id属性是元素在网页内的唯一标识符。 class…

207. 课程表 Python

文章目录 一、题目描述示例 1示例 2 二、代码三、解题思路 一、题目描述 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, …

入门Linux基本指令(2)

这篇文章主要提供一些对文件操作的Linux基本指令&#xff0c;希望对大家有所帮助&#xff0c;三连支持&#xff01; 目录 cp指令(复制) mv指令(剪切) nano指令 cat指令(打印文件内容) > 输出重定向 >> 追加重定向 < 输入重定向 more指令 less指令(推荐) …

影刀下载,插件安装

1、下载 在影刀官网下载&#xff1a;www.yingdao.com 2、谷歌插件安装 参考&#xff1a; 影刀插件安装各种方式 浏览器安装插件说明 - 影刀帮助中心 安装说明&#xff1a;驱动外置 Chrome 需要安装插件&#xff0c;并且保证此插件处于开启状态 方式一&#xff1a;用户头…

利用sklearn 实现线性回归、非线性回归

代码&#xff1a; import pandas as pd import numpy as np import matplotlib import random from matplotlib import pyplot as plt from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression# 创建虚拟数据 x np.array(r…

nacos安装与基础配置

源码 https://github.com/alibaba/nacos https://gitee.com/mirrors/Nacos 编译 git clone https://github.com/alibaba/nacos.git cd nacos/ mvn -Prelease-nacos -Dmaven.test.skiptrue clean install -U ls -al distribution/target/// change the $version to your ac…

24考研数据结构-队列1

目录 3.2队列&#xff08;Queue&#xff09;3.2.1队列的基本概念3.2.2队列的顺序存储结构3.2.2.1 队列存储的基本操作3.2.2.2 循环队列 基本操作和判空方式 \color{Red}{基本操作和判空方式} 基本操作和判空方式3.2.2.3 知识回顾 3.2队列&#xff08;Queue&#xff09; 3.2.1队…

解读RSAC 2021丨灵魂拷问:你的网络够“皮实”吗?

美国时间5月20日&#xff0c;RSA大会落下帷幕。大会虽已结束&#xff0c;讨论还在继续。对于大会的主题“Resilience”&#xff0c;每个厂商、每个人都有自己的解读。 山石网科新技术研究院全程关注RSA大会&#xff0c;对于“Resilience”&#xff0c;他们的解读简单易懂接地气…

Java面向对象 - 常用类——Object类

什么是Object类 Java中有一个比较特殊的类&#xff0c;就是 Object类&#xff0c;它是所有类的父类&#xff0c;如果一个类没有使用extends关键字明确标识继承另外一个类&#xff0c;那么这个类就默认继承 Object类。因此&#xff0c;Object 类是 Java 类层中的最高层类&#x…

【C语言进阶篇】指针都学完了吧!那回调函数的应用我不允许还有人不会!

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 &#x1f4cb; 前言&#x1f4ac; 函数指针数组&#x1f4ad; 函数指针数组的定义&#x1f4ad; 函数指针数组的…

Android性能优化之游戏引擎初始化ANR

近期&#xff0c;着手对bugly上的anr 处理&#xff0c;记录下优化的方向。 借用网上的一张图&#xff1a; 这里的anr 问题是属于主线程的call 耗时操作。需要使用trace 来获取发生anr前一些列的耗时方法调用时间&#xff0c;再次梳理业务&#xff0c;才可能解决。 问题1 ja…

Java Servlet实现下拉选择查询(双表)和单列模式

0目录 1.Servlet实现下拉选择查询&#xff08;双表&#xff09; 2.单列模式 1.Servlet实现下拉选择查询&#xff08;双表&#xff09; 新建数据库和表 实体类 接口方法 实现接方法 Servlet类 Web.xml List.jsp 页面效果 加入功能 2.单列模…

批发零售进销存哪个好?盘点5款主流批发零售进销存软件!

在我看来&#xff0c;几乎没有批发零售行业不需要做进销存管理&#xff0c;哪怕是路边一个小摊贩&#xff0c;也需要做进销存管理&#xff0c;但是传统的进销存过程中存在很多问题&#xff1a; 前后方协作困难&#xff1a;采购/销售/财务工作相互独立&#xff0c;工作入口不一…

机器学习深度学习——多层感知机

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——感知机 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所帮助 上一节…

Java阶段五Day14

Java阶段五Day14 文章目录 Java阶段五Day14分布式事务整合demo案例中架构&#xff0c;代码关系发送半消息本地事务完成检查补偿购物车消费 鲁班周边环境调整前端启动介绍启动前端 直接启动的项目gateway&#xff08;网关&#xff09;login&#xff08;登录注册&#xff09;atta…

DSA之图(4):图的应用

文章目录 0 图的应用1 生成树1.1 无向图的生成树1.2 最小生成树1.2.1 构造最小生成树1.2.2 Prim算法构造最小生成树1.2.3 Kruskal算法构造最小生成树1.2.4 两种算法的比较 1.3 最短路径1.3.1 两点间最短路径1.3.2 某源点到其他各点最短路径1.3.3 Dijkstra1.3.4 Floyd 1.4 拓扑排…

数据库表结构导出成文档

1.需求说明 在系统交付的过程中&#xff0c;有时候需要交付数据库的表结构&#xff0c;如果系统做的比较大&#xff0c;比如几百张表的时候&#xff0c;靠人力一张表一张的写&#xff0c;那就是一个奔溃啊。所以今天特意找了一下工具&#xff0c;小巧安装。比较好用。 2.安装…