【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};
    }
};
相关推荐
怀旧,4 小时前
【Linux系统编程】3. Linux基本指令(下)
linux·开发语言·c++
艾莉丝努力练剑4 小时前
【C++STL :stack && queue (三) 】优先级队列的使用以及底层实现
linux·开发语言·数据结构·c++·stl
web安全工具库5 小时前
Makefile 模式规则精讲:从 %.o: %.c 到静态模式规则的终极自动化
linux·运维·c语言·开发语言·数据库·自动化
從南走到北5 小时前
JAVA代泊车接机送机服务代客泊车系统源码支持小程序+APP+H5
java·开发语言·微信小程序·小程序
im_AMBER6 小时前
数据结构 06 线性结构
数据结构·学习·算法
earthzhang20218 小时前
【1028】字符菱形
c语言·开发语言·数据结构·c++·算法·青少年编程
papership8 小时前
【入门级-算法-3、基础算法:二分法】
数据结构·算法
通信小呆呆8 小时前
收发分离多基地雷达椭圆联合定位:原理、算法与误差分析
算法·目标检测·信息与通信·信号处理
earthzhang202110 小时前
第3讲:Go垃圾回收机制与性能优化
开发语言·jvm·数据结构·后端·性能优化·golang