双指针算法总结

本文介绍了双指针算法,包括快慢指针在检测循环链表、计算链表中点、找链表环起点和长度、有序数组操作(如两数之和、查找元素索引)以及检查回文字符串中的应用实例。
摘要由CSDN通过智能技术生成

双指针算法是一种高效的编程技巧,通常用于解决线性数据结构(如数组、链表)中的特定问题。这种算法的核心思想是利用两个或多个指针在数据结构中按不同策略移动,并通过它们的相对位置和指向的数据关系来解决问题。

基本类型:

  1. 快慢指针 (Fast-Slow Pointers)

    • 用于检测循环链表:设置两个指针,一个每次前进一格,另一个每次前进两格。如果存在环,则快指针最终会追上慢指针。
    • 计算链表的中点:同样基于快慢指针速度差原理,当快指针到达尾部时,慢指针所在位置即为中点。
    • 求解链表环的起点和长度:结合上述方法,在快慢指针相遇后,将慢指针重置到头结点,快慢指针以相同速度再次前进,相遇点即为环入口。
  2. 左右指针/对撞指针 (Two-Pointer)

    • 在有序数组中查找目标值对:例如,LeetCode上的题目“两数之和”系列,其中一个指针从左向右扫描,另一个从右向左扫描,寻找满足条件的元素对。
    • 删除排序数组中的重复项:一个指针作为读取器,另一个作为写入器,只将不重复的元素复制到新位置。
    • 检查回文字符串:使用两个指针分别从首尾开始遍历字符串,若所有对应位置字符相等,则字符串为回文。

应用场景举例:

1. 两数之和 (LeetCode #1)

#include <vector>
using namespace std;

vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> hash_map;
    for (int i = 0; i < nums.size(); ++i) {
        int complement = target - nums[i];
        if (hash_map.find(complement) != hash_map.end()) {
           return {hash_map[complement], i};
        }
     }
    // 如果没有找到符合条件的解,则返回空向量(在LeetCode中不需要)
    return {};
}

// 示例使用:
int main() {
    vector<int> nums = {2, 7, 11, 15};
    int target = 9;
    vector<int> indices = twoSum(nums, target);
    if (!indices.empty()) {
        cout << "Indices: " << indices[0] << ", " << indices[1] << endl;
    } else {
        cout << "No solution found." << endl;
    }
    return 0;
}

2. 有序数组中的第一个大于等于给定值的元素索引

#include <vector>
using namespace std;

int search_first_ge(const vector<int>& nums, int target) {
    int left = 0;
   int right = nums.size() - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] >= target) {
            if (mid == 0 || nums[mid - 1] < target) {
                return mid;
            }
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }

    // 如果没有找到符合条件的元素,则返回-1
    return -1;
}

// 示例调用
int main() {
    vector<int> nums = {1, 3, 4, 6, 8, 9};
    int target = 6;
    int index = search_first_ge(nums, target);
    cout << "First index greater or equal to " << target << ": " << index << endl;
    return 0;
}

3. 检查回文字符串

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

bool is_palindrome(string s) {
    int left = 0, right = s.length() - 1;
    
    while (left < right) {
        if (s[left] != s[right]) {
            return false;
        }
        ++left;
        --right;
    }
    
    return true;
}

// 示例调用
int main() {
    string s = "racecar";
    if (is_palindrome(s)) {
        cout << s << " is a palindrome." << endl;
    } else {
        cout << s << " is not a palindrome." << endl;
    }
    return 0;
}
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值