小工具知识网

当前位置: 首页 > 行业知识 > C++数据结构与算法——双指针法

行业知识

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

2026-10-26 10:46:43 来源:互联网转载

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

文章目录

  • 一、移除元素(力扣27)
  • 二、反转字符串(力扣344)
  • 三、替换数字(卡码网 54)
  • 四、翻转字符串里的单词(力扣151)
  • 五、反转链表(力扣206)
  • 六、删除链表的倒数第 N 个结点(力扣19)
  • 七、链表相交(力扣面试题 02.07)
  • 八、环形链表 II(力扣142)
  • 九、三数之和(力扣15)
  • 十、四数之和(力扣18)

    一、移除元素(力扣27)

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

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

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

    说明:

    为什么返回数值是整数,但输出的答案是数组呢?

    请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

    你可以想象内部操作如下:

    // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝

    int len = removeElement(nums, val);

    // 在函数里修改输入数组对于调用者是可见的。

    // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。

    for (int i = 0; i

    print(nums[i]);

    }

    class Solution {public:    int removeElement(vector& 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            if(nums[fast]!=val){                nums[slow] = nums[fast];                slow++;            }        }        return slow;    }};public:    void reverseString(vector        // 双指针解决        int begin =0;        int end = s.size()-1;        while(begin            // 交换            char temp = s[begin];            s[begin] = s[end];            s[end] = temp;            begin++;            end--;        }    }};    string inputS;    cin  inputS;    int count = 0;    // 遍历原来数组,记录其中数字的个数    for (int i = 0; i next;            slow = slow->next;        }        // 删除元素        ListNode * temp = slow->next;        slow->next = slow->next->next;        delete temp; // 删除        return dummyNode->next;    }};

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

    /** * 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;    }};

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

    /** * 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;    }};

    九、三数之和(力扣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 threeSum(vector& nums) {        // 先对数组排序        sort(nums.begin(),nums.end());        // 定义结果数组        vector result;        // 剪枝操作        if(nums[0]>0){            return {}; // 第一个元素都大于0了,说明不可能加起来等于0,直接返回空        }        for(int i=0;i            // 定义两个指针            int begin = i+1;            int end = nums.size()-1;            // 去重操作            if(i0&&nums[i]==nums[i-1]){                // 当前的i和i-1的元素是一样的                continue; // 跳过当前循环            }            while(begin                if((nums[i]+nums[begin]+nums[end])==0){                    result.push_back({nums[i],nums[begin],nums[end]});                    while(begin                        begin++;                    }                    while(begin                        end--;                    }                    begin++;                    end--;                }                else if((nums[i]+nums[begin]+nums[end])0){                    end--;                }                else{                    begin++;                }            }        }        return result;    }};public:    vector        // 先排序        sort(nums.begin(),nums.end());        // 定义最终返回数组        vector            // 剪枝            if(nums[0]=0&&nums[0]target){                break;            }            // 去重            if(i0&&nums[i]==nums[i-1]){                continue;            }            for(int j=i+1;j                // 剪枝                if(nums[i]+nums[j]target&&nums[j]=0){                    break;                }                // 去重                if(ji+1&&nums[j]==nums[j-1]){                    continue;                }                // 类似于三数之和                int begin = j+1;                int end = nums.size()-1;                while(begin                    if((long) nums[i]+nums[j]+nums[begin]+nums[end]==target){                        // 找到符合要求的数组,记录                        result.push_back({nums[i],nums[j],nums[begin],nums[end]});                        while(begin                            begin++;                        }                        while(begin                            end--;                        }                        begin++;                        end--;                    }                    else if((long)nums[i]+nums[j]+nums[begin]+nums[end]target){                        end--;                    }                    else{                        begin++;                    }                }            }        }        return result;    }};

上一篇:鼠标不能连接在计算机主机的端口怎么办

下一篇:怎么在qq空间改密码?