当前位置:   article > 正文

【C++刷题】优选算法——双指针

【C++刷题】优选算法——双指针
  1. 移动零
void moveZeroes(vector<int>& nums)
{
    size_t  front = 0;
    size_t back = 0;
    while(back < nums.size() && nums[back] != 0)
    {
        ++back;
    }
    front = back++;
    while(back < nums.size())
    {
        if(0 == nums[back])
        {
            ++back;
        }
        else
        {
            swap(nums[front++], nums[back++]);     
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  1. 复写零
    先找到最后一个被“复写”的数,然后从后向前完成“复写”操作。同时要注意处理一下边界情况。
void duplicateZeros(vector<int>& arr)
{
    int front = 0;
    int back = -1;
    while(true)
    {
        if(0 == arr[front])
        {
            back += 2;
        }
        else
        {
            back += 1;
        }
        if(back == arr.size())
        {
            --back;
            arr[back--] = 0;
            --front;
            break;
        }
        if(back == arr.size() - 1)
        {
            break;
        }
        ++front;
    }
    while(front >= 0)
    {
        if(arr[front] == 0)
        {
            arr[back--] = 0;
            arr[back--] = 0;
            --front;
        }
        else
        {
            arr[back--] = arr[front--];
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  1. 快乐数
// 方法一
bool isHappy(int n)
{
    unordered_set<int> res({n});
    int num = 0;
    while(true)
    {
        while(n != 0)
        {
            num += pow((n % 10), 2);
            n /= 10;
        }
        if(num == 1)
        {
            return true;
        }
        else if(res.find(num) != res.end())
        {
            return false;
        }
        else
        {
            res.insert(num);
        }
        n = num;
        num = 0;
    }
}
// 方法二
int Run(int num)
{
    int ret = 0;
    while(num != 0)
    {
        ret += pow((num % 10), 2);
        num /= 10;
    }
    return ret;
}

bool isHappy(int n)
{
    int slow = n;
    int fast = n;
    while (true)
    {
        slow = Run(slow);
        fast = Run(fast);
        fast = Run(fast);
        if (slow == fast && fast == 1)
        {
            return true;
        }
        else if (slow == fast)
        {
            return false;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  1. 盛最多水的容器
int maxArea(vector<int>& height)
{
    size_t left= 0;
    size_t right = height.size() - 1;
    size_t ret = (right - left) * min(height[left], height[right]);

    size_t tmp = 0;
    size_t area = 0;
    do
    {
        if(height[left] < height[right])
        {
            tmp = height[left];
            while(left < right && height[++left] <= tmp);
        }
        else
        {
            tmp = height[right];
            while(left < right && height[--right] <= tmp);
        }

        if(left < right)
        {
            area = (right - left) * min(height[left], height[right]);
            if(area > ret) ret = area;
        }
    }while(left < right);

    return ret;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  1. 有效三角形的个数
    利用单调性,先固定最大的数,在最大的数的左区间内使用双指针算法。
inline bool check(int side1, int side2, int side3)
{
    return (side1 + side2 > side3);
}
int triangleNumber(vector<int>& nums)
{
    if(nums.size() < 3) return 0;
    sort(nums.begin(), nums.end());

    size_t max_index = nums.size() - 1;
    size_t left_index = 0;
    size_t right_index = max_index - 1;
    int ret = 0;
    while(max_index > 1)
    {
        while(left_index < right_index)
        {
            if(check(nums[left_index], nums[right_index], nums[max_index]))
            {
                ret += (right_index - left_index);
                --right_index;
            }
            else
            {
                ++left_index;
            }
        }
        --max_index;
        left_index = 0;
        right_index = max_index - 1;
    }
    return ret;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  1. 查找总价格为目标值的两个商品
vector<int> twoSum(vector<int>& price, int target)
{
    size_t left = 0;
    size_t right = price.size() - 1;
    vector<int> v(2);
    while(left < right)
    {
        if(price[left] + price[right] < target)
        {
            ++left;
        }
        else if(price[left] + price[right] > target)
        {
            --right;
        }
        else
        {
            v[0] = price[left];
            v[1] = price[right];
            break;
        }
    }
    return v;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  1. 三数之和
    注意对去重的处理(跳过重复元素)。
vector<vector<int>> threeSum(vector<int>& nums)
{
    vector<vector<int>> vv;
    sort(nums.begin(), nums.end());

    size_t max_index = nums.size() - 1;
    size_t left_index = 0;
    size_t right_index = max_index - 1;
    while(max_index > 1)
    {
        while(left_index < right_index)
        {
            if(nums[left_index] + nums[right_index] + nums[max_index] > 0)
            {
                while(left_index < --right_index && nums[right_index] == nums[right_index + 1]);
            }
            else if(nums[left_index] + nums[right_index] + nums[max_index] < 0)
            {
                while(++left_index < right_index && nums[left_index] == nums[left_index - 1]);
            }
            else
            {
                vv.push_back({nums[left_index], nums[right_index], nums[max_index]});
                while(left_index < --right_index && nums[right_index] == nums[right_index + 1]); // or ++left_index
            }
        }
        while(--max_index > 1 && nums[max_index] == nums[max_index + 1]);
        left_index = 0;
        right_index = max_index - 1;
    }
    return vv;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  1. 四数之和
    结合三数之和解题。
long long Sum(long long num1, long long num2, long long num3)
{
    return num1 + num2 + num3;
}
void threeSum(vector<vector<int>>& vv, vector<int>& nums, size_t max_index, int max, int target)
{
    size_t left_index = 0;
    size_t right_index = max_index - 1;
    while(max_index > 1)
    {
        while(left_index < right_index)
        {
            if(Sum(nums[left_index], nums[right_index], nums[max_index]) > target)
            {
                while(left_index < --right_index && nums[right_index] == nums[right_index + 1]);
            }
            else if(Sum(nums[left_index], nums[right_index], nums[max_index]) < target)
            {
                while(++left_index < right_index && nums[left_index] == nums[left_index - 1]);
            }
            else
            {
                vv.push_back({nums[left_index], nums[right_index], nums[max_index], max});
                while(left_index < --right_index && nums[right_index] == nums[right_index + 1]);
            }
        }
        while(--max_index > 1 && nums[max_index] == nums[max_index + 1]);
        left_index = 0;
        right_index = max_index - 1;
    }
}
vector<vector<int>> fourSum(vector<int>& nums, int target)
{   
    vector<vector<int>> vv;
    if(nums.size() < 4) return vv;
    sort(nums.begin(), nums.end()); // 排序

    size_t max_index = nums.size() - 1; // 固定第4个数
    while(max_index > 2)
    {
        threeSum(vv, nums, max_index - 1, nums[max_index], target - nums[max_index]);
        while(--max_index > 2 && nums[max_index] == nums[max_index + 1]);
    }
    return vv;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/615429
推荐阅读
相关标签
  

闽ICP备14008679号