LeetCode刷题记录

LeetCode75

1:交替合并字符串

(1)string可以使用reserve进行开辟空间大小的限定
(2)算法中,开辟适当的空间代替逻辑复杂的代码可降低算法的时间效率

点击查看代码
class Solution {
public:
    string mergeAlternately(string word1, string word2) {
        int i,l1 = word1.size(),l2 = word2.size();
        string s;
        //指定s开辟的空间的大小
        s.reserve(l1+l2);
        //不要使用向word1中插元素的做法,会将复杂度上升为O(n*n),不值得
        for(i = 0;i<l1 && i<l2;i++){
            s+=word1[i];
            s+=word2[i];
        }
        if(l1>i){
            s+=word1.substr(i,l1);
        }
        if(l2>i){
            s+=word2.substr(i,l2);
        }
        return s;
    }
};

2:字符串的最大公因子

(1)求解两个数的最大公约数,C++的内置函数为_gcd(a,b)
(2)要注重数学思维,从题目给的信息进行深刻的分析
(3)字串问题中,若最大公约数的字串都不符合条件的话,其余字串一定不符合条件(cur mind)

点击查看代码
class Solution {
public:
    string gcdOfStrings(string str1, string str2) {
        if (str1 + str2 != str2 + str1) return "";
        return str1.substr(0, __gcd((int)str1.length(), (int)str2.length())); // __gcd() 为c++自带的求最大公约数的函数
    }
};

3:拥有最多糖果的孩子---希望大家都能快乐

点击查看代码
class Solution {
public:
    vector<bool> kidsWithCandies(vector<int>& candies, int extraCandies) {
        int m,n = candies.size();
        // 开辟指定空间后,意味着该空间已经被支配,故使用Push_back时会额外开辟空间
        vector<bool> v(n);
        // *max_element(start,end)返回数组中的最大值,max_element返回最大值的下标指针
        m = *max_element(candies.begin(),candies.end());
        for(int i = 0;i<n;i++){
            if(candies[i]+extraCandies>=m){
                v[i]=1;
            }else v[i]=0;
        }
        return v;
    }
};

4:种花问题

官方题解很复杂,不喜欢,这是一道简单题,个人认为没必要为了一点时间效率牺牲代码
值得注意的点是边界条件的判断以及全局判断条件的合理位置

点击查看代码
class Solution {
public:
    bool canPlaceFlowers(vector<int>& flowerbed, int n) {
        int m = flowerbed.size();
        for(int i = 0;i<m;i++){
            if(flowerbed[i]==0){
                //数组操作中,注意边界情况的判断!!!
                if(i==0||(i-1>0&&flowerbed[i-1]==0)){
                    if(i==m-1||(i+1<m&&flowerbed[i+1]==0)){
                        n--;
                        flowerbed[i] = 1;
                    }
                }
            }
            //判断全局返回结果,要将判断写在不受条件影响的位置
            //在已预知结果的情况下直接返回,节省运行时间
            if(n<=0) return true;
        }
        return false;
    }
};

5:反转字符串中的元音字母

涉及到反转,前后追击等,首尾操作的主用双指针

点击查看代码
class Solution {
public:
    string reverseVowels(string s) {
        unordered_map<char,int> mp;
        mp['a'] = 1; mp['A'] = 1;
        mp['e'] = 1; mp['E'] = 1;
        mp['i'] = 1; mp['I'] = 1;
        mp['o'] = 1; mp['O'] = 1;
        mp['u'] = 1; mp['U'] = 1;
        int len = s.length();
        for(int i = 0,j=len-1;i<j;i++){
            if(mp[s[i]]==1){
                while(i<j){
                    if(mp[s[j]]==1){
                        swap(s[i],s[j]);
                        j--;
                        break;
                    }
                    j--;
                }
            }
        }
        return s;
    }
};

6:反转字符串中的单词

官方题解中的双指针配合慢指针实现O(1)存储操作值得思考

点击查看代码
class Solution {
public:
    string reverseWords(string s) {
        // string res;
        // bool f=false;
        // int len = s.length();
        // //不使用头插的原因是,在每次插元素时后续元素均需进行移动
        // //该方法开辟了O(n)的空间
        // for(int i = len-1,j=len-1;i>=0;i--){
        //     if(s[i]!=' '){
        //         j=i;
        //         while(i>=0&&s[i]!=' '){
        //             i--;
        //         }
        //         if(f) res+=" ";
        //         res+=s.substr(i+1,j-i);
        //         f=true;
        //     }
        // }
        //官方题解是先将整个字符串反转,然后再逐个反转每个单词并顺便将空格去除,只需O(1)的存储空间
        reverse(s.begin(),s.end());
        int len = s.length(),idx=0,t;
        for(int start = 0;start<len;start++){
            if(s[start]!=' '){
                if(idx!=0) s[idx++]=' ';
                int end = start;
                while(end<len&&s[end]!=' ') s[idx++]=s[end++];
                reverse(s.begin()+idx-(end-start),s.begin()+idx);
                start=end;
            }
        }
        s.erase(s.begin()+idx,s.end());
        return s;
    }
};
posted @ 2023-09-24 12:52  小白*-*  阅读(12)  评论(0)    收藏  举报