【C++】使用双指针算法习题


🎆个人主页:夜晚中的人海

今日语录:用乐观的心态迎接困难,因为能打败你的,只有你自己。

文章目录

一、移动零

题目链接:移动零

题目描述:

解题思路:

1.我们可以使用两个指针cur和dest,一个指针(cur)负责遍历整个数组,另一个指针(dest)用来记录非零序列

2.在遍历过程中会出现两种情况,一个是当遇到的元素为0时,cur直接++;相反当遇到的元素为非0时,让dest指针先自增一(由于不知道最后⼀个非零元素在什么位置,因此初始化为-1 ),与cur指针指向的元素进行交换,不断重复上述过程就可以解决这一类问题

代码实现:

cpp 复制代码
class Solution 
{
public:
 void moveZeroes(vector<int>& nums) 
 {
 for(int cur = 0, dest = -1; cur < nums.size(); cur++)
 		if(nums[cur]) 
 				swap(nums[++dest], nums[cur]);
 }
};

二、复写零

题目链接:复写零

题目描述:

解决思路:

1.我们使用两个指针cur和dest,当cur小于数组个数时,不断重复下述过程: 判断cur指向的数据元素,如果它为0,那么dest指针移动两位,否则移动一位,每判断完一次cur指针都需要++

2.判断dest指针是否越界到数组大小为n的位置上,如果越界,则直接将数组中最后一个位置赋值给0,然后对两个指针进行回退,cur指针退一步,dest指针退两步

3.然后对数组进行复写,判断cur当前位置是否为0,如果不为0,则将cur位置的值赋值给dest,然后两个指针分别--,否则将dest位置修改为0,重复两次该操作,然后让cur--

代码实现:

cpp 复制代码
class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur = 0,dest = -1;
        int n = arr.size();
        while(cur < n)
        {
            if(arr[cur])
                dest++;
            else
                dest += 2;
            if(dest >= n - 1)
            {
                break;
            }
            cur++;
        }
        //处理边界情况
        if(dest == n)
        {
            arr[n - 1] = 0;
            cur--;
            dest -= 2;
        }
        while(cur >= 0)
        {
            if(arr[cur])
            {
                arr[dest--] = arr[cur--];
            }
            else
            {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }
};

三、快乐数

题目链接:快乐数

题目描述:

解题思路:
我们可以使用快慢指针的方法 ,由于快慢指针的特性(注:就是在一个环中,快指针总会追上慢指针,也就是它们会相遇在一个位置上),当相遇位置的值为1时,则这个数为快乐数,否则不是

代码实现:

cpp 复制代码
class Solution {
public:
    int bitsum(int num)
    {
        int sum = 0;
        int i;
        while(num)
        {
            i = num % 10;
            sum += i * i;
            num /= 10;
        }
        return sum;
    }

    bool isHappy(int n) {
        int slow = n,fast = bitsum(n);
        while(slow != fast)
        {
            slow = bitsum(slow);
            fast = bitsum(bitsum(fast));
        }
        return slow == 1;
    }
};

四、有效三角形的个数

题目链接:有效三角形的个数

题目描述:

解题思路:

一、我们可以使用暴力求解的方法,使用三层for循环,枚举出所有的三元组,判断是否构成三角形。但这个方法的时间复杂度太高了,效率低,因此采用另一种方法

二、我们可以对数组先进行排序,然后固定一个最长边nuns[i],使用两个指针left和right(left < right),采用对撞指针的方法,一个指向开头位置,另一个指向i - 1的位置上,如果nums[left] + nums[right] > nums[i],那么满足条件的三角形个数就为right - left,然后让right--再进行判断,否则让left++,不断重复上述过程

代码实现:

cpp 复制代码
class Solution {
public:
    int triangleNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n = nums.size();
        int ret = 0;
        for(int i = n - 1;i >= 2;i--)
        {
            int left = 0,right = i - 1;
            while(left < right)
            {
                if(nums[left] + nums[right] > nums[i])
                {
                    ret += right - left;
                    right--;
                }
                else
                {
                    left++;
                }
            }
        }
        return ret;
    }
};

五、和为s的两个数字

题目链接:和为s的两个数字

题目描述:

解题思路:

一、暴力求解:使用两层for循环,列出所有两个数字的组合,判断是否等于目标值(结果会超时)

二、使用对撞指针,一个指针left指向开头,另一个指针right指向数组最后一个的位置(left < right),判断price[left] + price[right]是否等于target,如果大于则让right--,否则让left++,不断重复此过程

代码实现:

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        int n = price.size();
        int left = 0,right = n - 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 {1,1};
    }
};
相关推荐
资深web全栈开发2 小时前
[特殊字符]图解 Golang 反射机制:从底层原理看动态类型的秘密
开发语言·后端·golang
报错小能手6 小时前
C++笔记——STL map
c++·笔记
独隅6 小时前
在 Lua 中,你可以使用 `os.date()` 函数轻松地将时间戳转换为格式化的时间字符串
开发语言·lua
思麟呀7 小时前
Linux的基础IO流
linux·运维·服务器·开发语言·c++
星释7 小时前
Rust 练习册 :Pythagorean Triplet与数学算法
开发语言·算法·rust
星释7 小时前
Rust 练习册 :Nth Prime与素数算法
开发语言·算法·rust
lkbhua莱克瓦248 小时前
Java基础——集合进阶3
java·开发语言·笔记
多喝开水少熬夜8 小时前
Trie树相关算法题java实现
java·开发语言·算法
QT 小鲜肉8 小时前
【QT/C++】Qt定时器QTimer类的实现方法详解(超详细)
开发语言·数据库·c++·笔记·qt·学习
WBluuue8 小时前
数据结构与算法:树上倍增与LCA
数据结构·c++·算法