C++ 双指针与链表

链表中的一些题目可以用双指针解决,我们将这些题目与其他双指针题目做了总结。

非链表题目

替换数字

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。

例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

输入:一个字符串 s,s 仅包含小写字母和数字字符。

输出:打印一个新的字符串,其中每个数字字符都被替换为了number

本题我们要从后往前进行新字符串的构造,时间复杂度为O(n);如果从前往后,则每次遇到数字都需移动后移后面的元素,时间复杂度为O(n^2)。

cpp 复制代码
#include<iostream>
#include<string>

using namespace std;

int main()
{
    string s;
    cin>>s;
    int sz=s.size();
    int numberNum=0;
    for(int i=0;i<sz;i++)
    {
        if(s[i] >= '0' && s[i] <= '9')
            numberNum++;
    }
    s.resize(sz-numberNum+numberNum*6);
    int left=sz-1,right=s.size()-1;
    while(left>=0)
    {
        if(s[left]>='a'&&s[left]<='z')
        {
            s[right]=s[left];
            right--;
            left--;
        }
        else
        {
            s[right--]='r';s[right--]='e';s[right--]='b';s[right--]='m';s[right--]='u';s[right--]='n';
            left--;
        }
    }
    cout<<s<<endl;
    return 0;
}

移除所有指定元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 你不需要考虑数组中超出新长度后面的元素。

本题当nums[fast]!=k时,就将fast赋值给slow,并且slow++,slow就是最后数组的大小。

cpp 复制代码
int delDuplicate(vector<int>&nums,int k)
{
    // 1 1 1 1 2 2 3
    int slow=0,fast=0;
    int sz=nums.size();
    while(fast<sz)
    {
        if(nums[fast]!=k)
        {
            nums[slow++]=nums[fast];
        }
        fast++;
    }
    return slow;
}
int main()
{
    vector<int> nums{1,1,1,1,2,2,3};
    cout<<delDuplicate(nums,1)<<endl;
    return 0;
}

三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 。请你找出所有满足条件且不重复的三元组。

注意: 答案中不可以包含重复的三元组。

示例:给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为: [ [-1, 0, 1], [-1, -1, 2] ]

本题的难点在于去重,是三元组结果的去重,而不是单个三元组内的去重。

  • 选择第一个元素何时去重?
  • 选择第二个、第三个元素何时去重?

双指针的思想是:首先固定一个元素a,对a去重。然后left=i+1,right=size-1。b+c+a时>0时,right--;否则left++。做这个操作的前提是,数组得先排序。选中一个三元组,对b、c进行去重操作。

cpp 复制代码
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int size=nums.size();
        vector<vector<int>> res;
        for(int i=0;i<size;i++)
        {
            if(nums[0]>0)
            {
                return {};
            }
            if(i>0&&nums[i]==nums[i-1])
                continue;
            int left=i+1,right=size-1;
            
            // 三个数,因此left<right
            while(left<right)
            {
                int a=nums[i],b=nums[left],c=nums[right];
                if(a+b+c>0)
                {
                    right--;
                }
                else if(a+b+c<0)
                {
                    left++;
                }
                else
                {
                    res.push_back({a,b,c});
                    while(left<right&&nums[left]==nums[left+1])
                        left++;
                    while(left<right&&nums[right]==nums[right-1])
                       right--;

                    right--;
                    left++;
                }
            }
        }
        return res;
    }
};

翻转字符串里的单词

链表

翻转链表

删除链表的倒数第N个节点

链表相交

环形链表

环形链表II

相关推荐
南宫生11 分钟前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_23 分钟前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
落魄君子35 分钟前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
冷眼看人间恩怨40 分钟前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
菜鸡中的奋斗鸡→挣扎鸡43 分钟前
滑动窗口 + 算法复习
数据结构·算法
红龙创客1 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin1 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
郭wes代码1 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
scan7241 小时前
LILAC采样算法
人工智能·算法·机器学习
菌菌的快乐生活2 小时前
理解支持向量机
算法·机器学习·支持向量机