0511刷题

这篇博客介绍了如何使用贪心算法解决LeetCode中的递增三元子序列问题,以及如何运用双指针法解决三数之和问题。文章详细解析了两种算法的实现过程,并提供了官方解答和优化后的代码实现,帮助读者理解算法思路。此外,还提及了一个反转字符串的题目,探讨了不同解法的可能性。
摘要由CSDN通过智能技术生成

0511刷题

LeetCode 334. 递增的三元子序列

LeetCode 334. 递增的三元子序列

贪心算法:

class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        int a = INT_MAX, b = INT_MAX;
        for(int x: nums)
            if(x <= a) a = x;
            else if(x <= b) b = x;
            else return true;
        return false;
    }
};

赋初始值的时候,已经满足second > first了,现在找第三个数third

(1) 如果third比second大,那就是找到了,直接返回true

(2) 如果third比second小,但是比first大,那就把second的值设为third,然后继续遍历找third

(3) 如果third比first还小,那就把first的值设为third,然后继续遍历找third(这样的话first会跑到second的后边,但是不要紧,因为在second的前边,老first还是满足的)

官方解答:

class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        int n = nums.size();
        if (n < 3) {
            return false;
        }
        int first = nums[0], second = INT_MAX;
        for (int i = 1; i < n; i++) {
            int num = nums[i];
            if (num > second) {
                return true;
            } else if (num > first) {
                second = num;
            } else {
                first = num;
            }
        }
        return false;
    }
};

LeetCode 15. 三数之和

LeetCode 15. 三数之和

1.双指针法:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;

        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();++i)
        {
            if(i>0&&nums[i]==nums[i-1]) continue;

            int left=i+1;
            int right=nums.size()-1;

            while(left<right)
            {
                if(nums[left]+nums[right]+nums[i]>0)
                {
                    right--;
                    while(left<right&&nums[right]==nums[right+1]) right--;
                }
                else if(nums[left]+nums[right]+nums[i]<0)
                {
                    left++;
                    while(left<right&&nums[left]==nums[left-1]) left++;
                }
                else
                {
                    result.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    while(left<right&&nums[right]==nums[right-1]) right--;
                    while(left<right&&nums[left]==nums[left+1]) left++;
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
};

2.哈希:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());//-4 -1 -1 0 1 2
        for(int i=0;i<nums.size();++i)
        {
            if(nums[i]>0) break;
            if(i>0&&nums[i]==nums[i-1]) continue;//三元组元素a去重
            
            unordered_set<int> set;
            for(int j=i+1;j<nums.size();++j)
            {
                if(j>i+2&&nums[j]==nums[j-1]&&nums[j-1]==nums[j-2]) continue;// 三元组元素b去重

                int tmp=0-(nums[i]+nums[j]);
                if(set.find(tmp)!=set.end())
                {
                    result.push_back({nums[i],nums[j],tmp});
                    set.erase(tmp);// 三元组元素c去重
                }
                else
                {
                    set.insert(nums[j]);
                }
            }
        }
        return result;
    }
};

注意

if(j>i+2&&nums[j]==nums[j-1]&&nums[j-1]==nums[j-2]) continue;// 三元组元素b去重

这个不是很明白。

LeetCode 541. 反转字符串 II

LeetCode 541. 反转字符串 II
class Solution {
public:
    string reverseStr(string s, int k) {
        for (int i = 0; i < s.size(); i += (2 * k)) 
        {
            // 1. 每隔 2k 个字符的前 k 个字符进行反转
            // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
            if (i + k <= s.size()) 
            {
                reverse(s.begin() + i, s.begin() + i + k );
                continue;
            }
            // 3. 剩余字符少于 k 个,则将剩余字符全部反转。
            reverse(s.begin() + i, s.end());
        }
        return s;
    }
};

debug解法,还未debug:

class Solution {
public:
    string reverseStr(string s, int k) {
        int count=1;
        string result="";
        string str="";
        for(int i=0;i<s.size();++i)
        {
            if(count<=2*k) 
            {
                count++;
                str+=s[i];
                if(i==s.size()-1)
                {
                    if(str.size()<k) 
                    {
                        //如果剩余字符少于 k 个,则将剩余字符全部反转。
                        string newString1=str;
                        int left=0;
                        int right=newString1.size()-1;
                        while(left<right)
                        {
                            char tmp=newString1[left];
                            newString1[left]=newString1[right];
                            newString1[right]=tmp;
                            left++;
                            right--;
                        }
                        result+=newString1;
                    }
                    else 
                    {
                        //如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
                        string newString2="";
                        for(int i=0;i<k;++i)
                        {
                            newString2+=str[i];
                        }
                        int left=0;
                        int right=k-1;
                        while(left<right)
                        {
                            char tmp=newString2[left];
                            newString2[left]=newString2[right];
                            newString2[right]=tmp;
                            left++;
                            right--;
                        }
                        for(int i=k;i<str.size();++i)
                        {
                            newString2+=str[i];
                        }
                        result+=newString2;
                    }
                }
            }
            else if(count>2*k)
            {
                //反转这 2k 字符中的前 k 个字符。
                string newString3="";
                for(int i=0;i<k;++i)
                {
                    newString3+=str[i];
                }
                int left=0;
                int right=k-1;
                while(left<right)
                {
                    char tmp=newString3[left];
                    newString3[left]=newString3[right];
                    newString3[right]=tmp;
                    left++;
                    right--;
                }
                for(int i=k;i<str.size();++i)
                {
                    newString3+=str[i];
                }
                result+=newString3;
                count=1;
                str="";
                newString3="";
            } 
        }
        return result;
    }
    
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值