You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中双指针、多指针的实际用途是什么?

嘿,作为刚接触C++的新手,搞不懂双指针、三指针到底干啥用太正常了——我当初学的时候也对着这些概念挠头半天!别着急,我用最直白的方式给你拆解清楚,搭配简单的代码例子,保证你看完能get到它们的核心作用。

先搞懂:双指针到底能解决啥问题?

双指针其实就是用两个指针变量(可以是指向数组元素的指针,也可以是链表的节点指针)配合着移动,核心是减少不必要的遍历,把时间复杂度降下来,常见的有两种典型用法:

1. 左右指针(相向移动):处理有序数组/字符串的问题

比如经典的“有序数组中找两个数之和等于目标值”,如果不用双指针,你可能会嵌套两层循环遍历,时间复杂度是O(n²),但用左右指针的话,只需要O(n)的时间。

举个代码例子:

#include <vector>
#include <iostream>
using namespace std;

vector<int> twoSum(vector<int>& nums, int target) {
    int left = 0; // 左指针从数组开头出发
    int right = nums.size() - 1; // 右指针从数组末尾出发
    
    while (left < right) {
        int sum = nums[left] + nums[right];
        if (sum == target) {
            return {left, right}; // 找到目标,返回索引
        } else if (sum < target) {
            left++; // 和太小,左指针右移,增大总和
        } else {
            right--; // 和太大,右指针左移,减小总和
        }
    }
    return {}; // 没找到返回空
}

int main() {
    vector<int> nums = {2,7,11,15};
    int target = 9;
    vector<int> result = twoSum(nums, target);
    cout << "索引:" << result[0] << " 和 " << result[1] << endl;
    return 0;
}

这里的逻辑很简单:因为数组是有序的,所以通过调整左右指针的位置,就能快速缩小范围,不用挨个试所有组合。类似的还有回文字符串判断、有序数组去重,都是这个思路。

2. 快慢指针(同向移动):处理链表或数组的“追击”问题

比如判断链表有没有环,或者找链表的中间节点,快慢指针简直是神器。

举个判断链表环的例子:

#include <iostream>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

bool hasCycle(ListNode *head) {
    if (head == nullptr || head->next == nullptr) {
        return false; // 空链表或只有一个节点,肯定没环
    }
    ListNode* slow = head; // 慢指针每次走1步
    ListNode* fast = head->next; // 快指针每次走2步
    
    while (slow != fast) {
        if (fast == nullptr || fast->next == nullptr) {
            return false; // 快指针走到头了,说明没环
        }
        slow = slow->next;
        fast = fast->next->next;
    }
    return true; // 快慢指针相遇,说明有环
}

int main() {
    // 构造一个带环的链表:1->2->3->2
    ListNode* head = new ListNode(1);
    head->next = new ListNode(2);
    head->next->next = new ListNode(3);
    head->next->next->next = head->next;
    
    cout << (hasCycle(head) ? "有环" : "无环") << endl;
    return 0;
}

这里的思路就像操场跑步,跑得快的人总会追上跑得慢的——如果链表有环,快指针一定会和慢指针相遇;如果没环,快指针会先走到链表末尾。另外找链表中间节点也是一样,快指针走到头时,慢指针正好在中间。

再来说:三指针的应用场景

三指针其实是双指针的延伸,主要用来解决三个元素组合的问题,最典型的就是“有序数组的三数之和”,要求找出所有不重复的三元组,使得它们的和为0。

直接上代码例子:

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

vector<vector<int>> threeSum(vector<int>& nums) {
    vector<vector<int>> result;
    sort(nums.begin(), nums.end()); // 先排序,方便用指针调整
    int n = nums.size();
    
    for (int i = 0; i < n; i++) {
        if (nums[i] > 0) break; // 第一个数就大于0,后面的数更大,不可能和为0
        if (i > 0 && nums[i] == nums[i-1]) continue; // 跳过重复的第一个数
        
        int left = i + 1; // 左指针在i的下一位
        int right = n - 1; // 右指针在数组末尾
        
        while (left < right) {
            int sum = nums[i] + nums[left] + nums[right];
            if (sum == 0) {
                result.push_back({nums[i], nums[left], nums[right]});
                // 跳过重复的左指针元素
                while (left < right && nums[left] == nums[left+1]) left++;
                // 跳过重复的右指针元素
                while (left < right && nums[right] == nums[right-1]) right--;
                left++;
                right--;
            } else if (sum < 0) {
                left++; // 和太小,左指针右移增大总和
            } else {
                right--; // 和太大,右指针左移减小总和
            }
        }
    }
    return result;
}

int main() {
    vector<int> nums = {-1,0,1,2,-1,-4};
    vector<vector<int>> result = threeSum(nums);
    for (auto& triplet : result) {
        cout << triplet[0] << ", " << triplet[1] << ", " << triplet[2] << endl;
    }
    return 0;
}

这里的逻辑是:先固定第一个数,然后用左右两个指针在剩下的元素里找另外两个数,让三者之和为0。本质上是把三数问题转化成了双指针的两数问题,时间复杂度从O(n³)降到了O(n²),效率提升非常明显。

总结一下核心作用

不管是双指针还是三指针,它们的核心都是用多个指针的配合移动,减少重复的遍历操作,从而优化算法的时间复杂度,把原本需要嵌套多层循环的问题,简化成线性或者线性平方级别的时间消耗。而且这些思路不仅限于C++,在其他语言里也一样通用,掌握了之后能解决很多算法题里的经典问题。

内容的提问来源于stack exchange,提问作者Mark Green

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:30:06