算法1:双指针

文章目录

移动零

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int des = -1, cur = 0;
        while(cur < nums.size()){
            if(nums[cur] == 0){
                cur++;
            }
            else{
                swap(nums[++des],nums[cur++]); 
            }
        }
    }
};

复习零

先找到最后一个复写的数,再从右往左复写
在这里插入图片描述

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int dest = -1, cur = 0;
        while (cur < arr.size()) {
            if (arr[cur] == 0)
                dest += 2;
            else
                dest++;
            if (dest >= arr.size() - 1)
                break;
            cur++;
        }

        if (dest == arr.size()) {
            arr[--dest] = arr[cur];
            --dest;
            --cur;
        }

        while (cur >= 0) {
            arr[dest] = arr[cur];
            if (arr[dest] == 0)
                arr[--dest] = 0;
            dest--;
            cur--;
        }
    }
};
补:这里也可以采用头尾指针,时间及空间复杂度不变

3.快乐数
扩展:鸽巢原理
在这里插入图片描述

2

4.盛最多水容器

class Solution {
public:
    int maxArea(vector<int>& height) {
        int v = 0;
        int left = 0, right = height.size() - 1;
        int temp = 0;
        while (left < right) {
            v = max(v, (right - left) * min(height[left], height[right]));
            if (height[left] < height[right]) {
                temp = left;
                while (height[temp] >= height[left] && left < right)
                    left++;
            } else {
                temp = right;
                while (height[temp] >= height[right] && left < right)
                    right--;
            }
        }
        return v;
    }
};

5.有效三角形个数
暴力枚举会超时
在这里插入图片描述

class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        if (nums.size() < 3)
            return 0;
        sort(nums.begin(), nums.end());
        int ans = 0;
        int left = 0, right = nums.size() - 2, key = nums.size() - 1;
        while (key > 1) {
            left = 0;
            right = key - 1;
            while (left < right) {
                if (nums[left] + nums[right] <= nums[key])
                    left++;
                else {
                    ans += (right - left);
                    right--;
                }
            }
            key--;
        }
        return ans;
    }
};

6.和为s的两个数

class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        vector<int> res;
        int left = 0, right = price.size() - 1;
        while(left < right)
        {
            if(price[left] + price[right] > target)
                right--;
            else if(price[left] + price[right] < target)
                left++;
            else{
                res.push_back(price[left]);
                res.push_back(price[right]);
                return res;
            }
        }
        return res;
    }
};
class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        int left = 0, right = price.size() - 1;
        while(left < right)
        {
            if(price[left] + price[right] > target)
                right--;
            else if(price[left] + price[right] < target)
                left++;
            else{
                return {price[left],price[right]};
            }
        }
        return {0,0};;
    }
};

7.三数之和
在这里插入图片描述

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        if (nums.size() < 3)
            return {};
        sort(nums.begin(), nums.end(),
             [](int a, int b) -> bool { return a < b; });
        vector<vector<int>> res;
        int key = 0, left = 1, right = nums.size() - 1;
        while (key < nums.size() - 2) {
            left = key + 1;
            right = nums.size() - 1;
            while (left < right) {
                if (nums[left] + nums[right] == -nums[key]) {
                    res.push_back({nums[left], nums[right], nums[key]});
                    left++;right--;
                    while (left < right && nums[left - 1] == nums[left])
                        left++;
                    while (left < right && nums[right + 1] == nums[right])
                        right--;
                } else if (nums[left] + nums[right] < -nums[key]) {
                    left++;
                    while (left < right && nums[left - 1] == nums[left])
                        left++;
                } else {
                    right--;
                    while (left < right && nums[right + 1] == nums[right])
                        right--;
                }
            }
            key++;
            while (key < nums.size() - 2 && nums[key] == nums[key - 1])
                key++;
            if (nums[key] > 0)
                break;
        }

        return res;
    }
};

8.四数之和
利用三数之和求解

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        vector<vector<int>> res;
        int a, b, left, right;
        a = b = left = right = 0;
        int olda = 0;
        int oldb = 0;
        while (a < n - 3) {
            b = a + 1;
            int T_A = target - nums[a];
            while (b < n - 2) {
                left = b + 1;
                right = n - 1;
                long long T_B = (long long)T_A - nums[b];
                while (left < right) {
                    if (nums[left] + nums[right] == T_B) {
                        res.push_back(
                            {nums[a], nums[b], nums[left++], nums[right--]});
                        while (left < right && nums[left] == nums[left - 1])
                            left++;
                        while (left < right && nums[right] == nums[right + 1])
                            right--;
                        while (left < right && nums[left] == nums[left - 1])
                            left++;
                        while (left < right && nums[right] == nums[right + 1])
                            right--;
                    } else if (nums[left] + nums[right] < T_B) {
                        left++;
                        while (left < right && nums[left] == nums[left - 1])
                            left++;
                    } else {
                        right--;
                        while (left < right && nums[right] == nums[right + 1])
                            right--;
                    }
                }
                // 对b去重
                oldb = nums[b];
                while (b < n - 2 && oldb == nums[b])
                    b++;
            }
            // 对a去重
            olda = nums[a];
            while (a < n - 3 && olda == nums[a])
                a++;
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值