C++数据结构与算法——双指针法

这篇具有很好参考价值的文章主要介绍了C++数据结构与算法——双指针法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++第二阶段——数据结构和算法,之前学过一点点数据结构,当时是基于Python来学习的,现在基于C++查漏补缺,尤其是树的部分。这一部分计划一个月,主要利用代码随想录来学习,刷题使用力扣网站,不定时更新,欢迎关注!

一、移除元素(力扣27)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        // 利用快慢指针进行删除
        // 1. 判断是否只有零个或一个元素,防止索引超出数组长度
        if(nums.size()==1){
            if(nums[0]==val){
                return 0;
            }
            else{
                return 1;
            }
        }
        if (nums.size()==0){
            return 0;
        }

        int slow =0;
        for(int fast=0;fast<nums.size();fast++){
            if(nums[fast]!=val){
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

二、反转字符串(力扣344)

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]
示例 2:
输入:s = [“H”,“a”,“n”,“n”,“a”,“h”]
输出:[“h”,“a”,“n”,“n”,“a”,“H”]
提示:
1 <= s.length <= 105
s[i] 都是 ASCII 码表中的可打印字符

class Solution {
public:
    void reverseString(vector<char>& s) {
        // 双指针解决
        int begin =0;
        int end = s.size()-1;
        while(begin<end){
            // 交换
            char temp = s[begin];
            s[begin] = s[end];
            s[end] = temp;
            begin++;
            end--;
        }
    }
};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

三、替换数字(卡码网 54)

题目描述
给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 “a1b2c3”,函数应该将其转换为 “anumberbnumbercnumber”。
输入描述
输入一个字符串 s,s 仅包含小写字母和数字字符。
输出描述
打印一个新的字符串,其中每个数字字符都被替换为了number
输入示例
a1b2c3
输出示例
anumberbnumbercnumber
提示信息
数据范围:
1 <= s.length < 10000。

#include <iostream>
using namespace std;
 
 
int main() {
    string inputS;
    cin >> inputS;
    int count = 0;
    // 遍历原来数组,记录其中数字的个数
    for (int i = 0; i < inputS.length(); i++) {
        if (inputS[i] <= '9' && inputS[i]>='0') {
            count++;
        }
    }
    int FLength = inputS.length();
    // resize 原来的字符串
    inputS.resize(FLength + count * 5);
    // 替换原来字符串中的字符,从后向前替换
    int j = inputS.length()-1;
    for (int i = FLength - 1; j>i; i--,j--) {
        if (inputS[i] <= '9' && inputS[i]>='0') {
            // 是数字要替换
            inputS[j] = 'r';
            inputS[j-1] = 'e';
            inputS[j-2] = 'b';
            inputS[j-3] = 'm';
            inputS[j-4] = 'u';
            inputS[j-5] = 'n';
            j -= 5;
        }
        else {
            inputS[j] = inputS[i];
        }
    }
    cout << inputS << endl;
    system("pause");
    return 0;
 
}

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

四、翻转字符串里的单词(力扣151)

给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: “the sky is blue”
输出: “blue is sky the”
示例 2:
输入: " hello world! "
输出: “world! hello”
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

class Solution {
public:
    string reverseWords(string s) {
        // 去除空格
        removeSpace(s);
        // // 翻转整个句子
        reverse(s.begin(), s.end());
        // 翻转每个单词
        // 首先找到每个单词的位置
        int slow=0;
        for(int fast=0;fast<s.length();fast++){
            if(s[fast+1]==' ' || fast==s.length()-1){
                reverseWord(s,slow,fast);
                slow = fast+2;
            }
        }
        return s;
    }
    // 翻转每个单词
    void reverseWord(string& s, int begin, int end) {
        while (begin < end) {
            swap(s[begin], s[end]);
            begin++;
            end--;
        }
    }
    // 去除字符串中多余的空格
    void removeSpace(string& s) {
        // 快慢指针去除空格
        int slow = 0;
        for (int fast = 0; fast < s.length(); fast++) {
            if (s[fast] != ' ') {
                // 不为空格才进行下面的操作
                // 添加每个单词之间的空格,句子开头不加
                if (slow != 0) {
                    s[slow] = ' ';
                    slow++;
                }
                while (fast<s.size() && s[fast] != ' ') {
                    s[slow] = s[fast];
                    slow++;
                    fast++;
                }
            }
        }
    s.resize(slow);
    }

};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

五、反转链表(力扣206)

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==NULL||head->next==NULL){
            // 只有一个结点
            return head;
        }
        // 定义两个指针,一个指前面的,一指后面的
        ListNode *pre = NULL;
        ListNode *cur = head;
        while(cur!=NULL){
            // 用一个值去接收cur
            ListNode *temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }

};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

六、删除链表的倒数第 N 个结点(力扣19)

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if (head==NULL){
            return head;
        }

        ListNode * dummyNode = new ListNode(0);
        dummyNode->next = head;
        // 使用快慢指针
        ListNode* fast = dummyNode;
        ListNode* slow = dummyNode;
        while(n--){
            // 快指针先走n个
            fast = fast->next;
        }
        while(fast!=NULL&&fast->next!=NULL){
            fast = fast->next;
            slow = slow->next;
        }
        // 删除元素
        ListNode * temp = slow->next;
        slow->next = slow->next->next;
        delete temp; // 删除
        return dummyNode->next;
    }
};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

七、链表相交(力扣面试题 02.07)

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        // 实际上是找相等的结点,不是值相等,而是 是同一个结点
        // 将两个链表右对齐
        // 求两个链表的长度
        if(headA==NULL||headB==NULL){
            return NULL;
        }
        int lenA =1;
        int lenB =1;
        ListNode * curA = headA;
        ListNode * curB = headB;
        while(curA->next!=NULL){
            lenA++;
            curA = curA->next;
        }
        while(curB->next!=NULL){
            lenB++;
            curB = curB->next;
        }
        // 找最短的链表
        int minLen =min(lenA,lenB);
        // AB需要移动的长度
        int needA= lenA-minLen;
        int needB = lenB - minLen;
        // 右对齐两个节点
        while(needA--){
            headA = headA->next;
        }
        while(needB--){
            headB = headB->next;
        }
        // 比较之后的链表是否相同
        while(headA!=NULL||headB!=NULL){
            if(headA== headB){
                return headA;
            }
            else{
                headA = headA->next;
                headB = headB ->next;
            }
        }
        return NULL;
    }
};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

八、环形链表 II(力扣142)

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode * first = head;
        ListNode * slow = head;
        while(first!=NULL&&first->next!=NULL){
            first = first->next->next;
            slow = slow->next;
            if(first==slow){
                // 此时相遇
                ListNode * index1 = first;
                ListNode * index2 = head;
                // 找入环口
                while(index1!=index2){
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index1;
            }
        }
        return NULL;

    }
};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

九、三数之和(力扣15)

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        // 先对数组排序
        sort(nums.begin(),nums.end());
        // 定义结果数组
        vector<vector<int>> result;
        // 剪枝操作
        if(nums[0]>0){
            return {}; // 第一个元素都大于0了,说明不可能加起来等于0,直接返回空
        }
        for(int i=0;i<nums.size();i++){
            // 定义两个指针
            int begin = i+1;
            int end = nums.size()-1;
            // 去重操作
            if(i>0&&nums[i]==nums[i-1]){
                // 当前的i和i-1的元素是一样的
                continue; // 跳过当前循环
            }
            while(begin<end){
                if((nums[i]+nums[begin]+nums[end])==0){
                    result.push_back({nums[i],nums[begin],nums[end]});
                    while(begin<end&&nums[begin]==nums[begin+1]){
                        begin++;
                    }
                    while(begin<end&&nums[end]==nums[end-1]){
                        end--;
                    }
                    begin++;
                    end--;
                }
                else if((nums[i]+nums[begin]+nums[end])>0){
                    end--;
                }
                else{
                    begin++;
                }

            }


        }
        return result;
    }
};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法

十、四数之和(力扣18)

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
提示:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        // 先排序
        sort(nums.begin(),nums.end());
        // 定义最终返回数组
        vector<vector<int>> result;
        // 类似于三数之和,多了一层循环
        for (int i=0;i<nums.size();i++){
            // 剪枝
            if(nums[0]>=0&&nums[0]>target){
                break;
            }
            // 去重
            if(i>0&&nums[i]==nums[i-1]){
                continue;
            }
            for(int j=i+1;j<nums.size();j++){
                // 剪枝
                if(nums[i]+nums[j]>target&&nums[j]>=0){
                    break;
                }
                // 去重
                if(j>i+1&&nums[j]==nums[j-1]){
                    continue;
                }
                // 类似于三数之和
                int begin = j+1;
                int end = nums.size()-1;
                while(begin<end){
                    if((long) nums[i]+nums[j]+nums[begin]+nums[end]==target){
                        // 找到符合要求的数组,记录
                        result.push_back({nums[i],nums[j],nums[begin],nums[end]});
                        while(begin<end&&nums[begin]==nums[begin+1]){
                            begin++;
                        }
                        while(begin<end&&nums[end]==nums[end-1]){
                            end--;
                        }
                        begin++;
                        end--;
                    }
                    else if((long)nums[i]+nums[j]+nums[begin]+nums[end]>target){
                        end--;
                    }
                    else{
                        begin++;
                    }
                }
            }
        }
        return result;
    }
};

C++数据结构与算法——双指针法,C++学习,算法与数据结构系统学习,c++,java,算法文章来源地址https://www.toymoban.com/news/detail-829653.html

到了这里,关于C++数据结构与算法——双指针法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 『初阶数据结构 • C语言』⑰ - 快速排序(hoare法、挖坑法、前后指针法与非递归实现)

    目录 1. hoare法 方法与步骤 代码实现 2. 挖坑法 方法与步骤 代码实现 3. 前后指针法 方法与步骤 代码实现  4. 快速排序的缺点与优化 1.快速排序的缺点 2.快速排序的优化 ① 三数取中法选 key 代码实现 ② 小区间优化 代码实现 5. 快速排序的非递归实现 附录﹡完整源码 快速排序

    2024年02月13日
    浏览(43)
  • C语言实现快排核心思想(双指针法)

     核心代码: 这就是每一趟快排的实现代码,由上面的动图,我们能知道前后指针法的核心是玩好cur和prev这两个指针,具体的逻辑是cur找比key小的值,找到就prev++,然后prev和cur的值就进行交换,但是总不能自己跟自己交换吧,这就是多此一举了,所以我们在代码中的if语句里

    2024年02月02日
    浏览(57)
  • c语言快速排序(霍尔法、挖坑法、双指针法)图文详解

      快速排序是一种非常常用的排序方法,它在1962由C. A. R. Hoare(霍尔)提的一种二叉树结构的交换排序方法,故因此它又被称为 霍尔划分 ,它基于分治的思想,所以整体思路是递归进行的。 1.先选取一个key,关于key值的选取,一般是选数组第一个元素,数组中间元素,数组

    2024年02月02日
    浏览(35)
  • 【C++】数据结构与算法:常用排序算法

    😏 ★,° :.☆( ̄▽ ̄)/$: .°★ 😏 这篇文章主要介绍常用排序算法。 学其所用,用其所学。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路🥞 排序算法是计算机科学中常见的一类算法,用于将一组数据按照特定的顺序进行排

    2024年02月14日
    浏览(49)
  • 【数据结构与算法C++实现】3、排序算法

    原视频为左程云的B站教学 外层循环 :n个数需要冒n-1个泡上去,剩下的一个必然是最小的。所以外层循环执行n-1轮 内层循环 :比大小,第1个泡需要比n-1次,第2个泡,比较n-2次… 选择: 每次从待排序序列中选择 最小的一个 放在已排序序列的后一个位置 原理类似于对扑克牌

    2024年02月11日
    浏览(58)
  • C++基础-介绍·数据结构·排序·算法

    C++是一门风格严谨又不失自由的开发语言,提供了完整的内存管理、支持函数式编程和面向对象编程,支持模板、多继承、多实现、重载、重写等多态特性。 优势在于目前90%的操作系统、数据库、应用基础架构、硬件嵌入式等都是使用C/C++制作的,而C++是对C的标准扩展,掌握

    2024年02月03日
    浏览(45)
  • C++数据结构与算法——哈希表

    C++第二阶段——数据结构和算法,之前学过一点点数据结构,当时是基于Python来学习的,现在基于C++查漏补缺,尤其是树的部分。这一部分计划一个月,主要利用代码随想录来学习,刷题使用力扣网站,不定时更新,欢迎关注! 给定两个字符串 s 和 t ,编写一个函数来判断

    2024年02月19日
    浏览(58)
  • C++数据结构与算法——栈与队列

    C++第二阶段——数据结构和算法,之前学过一点点数据结构,当时是基于Python来学习的,现在基于C++查漏补缺,尤其是树的部分。这一部分计划一个月,主要利用代码随想录来学习,刷题使用力扣网站,不定时更新,欢迎关注! 请你仅使用两个栈实现先入先出队列。队列应当

    2024年02月20日
    浏览(44)
  • 链表综合算法设计(c++数据结构)

      一、设计内容 已知简单的人事信息系统中职工记录包含职工编号(no)、职工姓名(name)、部门名称(depname)、职称(title)和工资数(salary)等信息(可以增加其他信息),设计并完成一个简单的人事信息管理系统,要求完成但不限于以下功能: (1)    增加一个职工信息

    2024年02月02日
    浏览(57)
  • C++中的算法与数据结构优化技巧

    在C++编程中,算法和数据结构的优化是提高程序性能和效率的关键因素之一。下面是一些常见的算法和数据结构优化技巧,希望对您有帮助: 选择合适的数据结构:数据结构的选择对算法效率有重要影响。根据具体问题的需求,选择合适的数据结构,如数组、链表、树、散列

    2024年01月17日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包