双指针专题

本文介绍了五种编程问题的解决方案,均涉及字符串处理和双指针技巧:回文串验证、子序列判断、两数之和、三数之和以及盛水最多的容器。使用Python和C语言实现,展示了双指针优化算法在这些问题中的应用。
摘要由CSDN通过智能技术生成

1. 验证回文串

思路:先去除奇怪的字符,并把所有大写字母转成小写字母,然后双指针一头一尾一起往中间移动

需要与字符串相关的函数,就不用C了,C轮子太少

python

class Solution:
    def isPalindrome(self, s: str) -> bool:
        n = len(s)
        s = s.lower()
        list = []
        for i in range(n):
            if s[i] >= 'a' and s[i] <= 'z':
                list.append(s[i])
            elif s[i] >= '0' and s[i] <= '9':
                list.append(s[i])
        if n <= 1:
            return True
        i,j = 0, len(list)-1
        while(i <= j):
            if list[i] == list[j]:
                i += 1
                j -= 1
            else:
                return False
        return True

2.判断子序列 

思路:分别两个指针指在s和t,挨个往前,相同就一起+1,不同就t的+1,s遍历完就算存在

C

bool isSubsequence(char* s, char* t) {
    int n = strlen(s);
    int m = strlen(t);
    int i = 0, j = 0;
    while(i<n && j<m){
        if(s[i] == t[j]){
            i++;
            j++;
        }else{
            j++;
        }
    }
    if(i == n){
        return true;
    }
    return false;
}

 3. 两数之和

思路:经典题目,可以暴力但时间复杂度O(n**2),也可以一层枚举+二分查找,复杂度O(nlogn),最快双指针,可以充分利用数组非递减,一头一尾两个指针,计算和,小了左边的右移,大了右边的左移

python

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        ans = []
        i,j = 0, len(numbers)-1
        while(i<j):
            sum = numbers[i]+numbers[j]
            if sum == target:
                ans.append(i+1)
                ans.append(j+1)
                return ans
            elif sum > target:
                j -= 1
            else:
                i += 1
        return ans

4. 三数之和

思路:一层枚举+双指针,需要先排序,主要点在于判断边界条件,由于要求不能重复, 因此指针移动时要看看值是不是一样,一样需要跳过

python

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums = sorted(nums)
        n = len(nums)
        if nums[0] == 0 and nums[n-1] == 0:
            return [[0,0,0]]
        ans = []
        for k in range(0, n-2):
            if nums[k] > 0:
                break
            if nums[k] == nums[k-1] and k > 0:
                continue
            i,j = k+1,n-1
            while(i < j):
                sum = nums[i] + nums[j] + nums[k]
                if sum > 0:
                    j -= 1
                    while i < j and nums[j] == nums[j+1]: j -= 1 
                elif sum < 0:
                    i += 1
                    while i < j and nums[i] == nums[i-1]: i += 1
                else:
                    list = [nums[k], nums[i], nums[j]]
                    ans.append(list)
                    i += 1
                    j -= 1
                    while i < j and nums[i] == nums[i-1]: i += 1
                    while i < j and nums[j] == nums[j+1]: j -= 1 
        return ans

5. 盛水最多的容器

 思路:双指针一头一尾,每次计算一下,然后对比,谁小谁移动。

为什么谁小谁移动可以得出解呢,因为如果小的固定,那么另外一个无论怎么移动,水都不会更多了,所以要移动小的,看看有没有大一点的,能抬高杯壁上限

python

class Solution:
    def maxArea(self, height: List[int]) -> int:
        n = len(height)
        i,j = 0,n-1
        ans = 0
        while i < j:
            ans = max(min(height[i], height[j])*(j-i),ans)
            if height[i] <= height[j]:
                i += 1
            else:
                j -= 1
        return ans

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值