DataWhale算法学习笔记day12-14

一、双指针

指的是在遍历数组的时候采用两个指针访问的方法。如果两个指针方向相反,则称 对撞指针 ;如果两个指针方向相同,则称 快慢指针 ;如果两个指针分属于不同的数组,则称 分离双指针 。 在数组问题中,暴力算法的时间复杂度往往是O(n*n),但双指针利用数组区间单调性的性质,可将时间复杂度降至O(n)。

1.对撞指针

指的是left、right两个指针分别指向数组第零个和最后一个元素,然后左指针不断向右递增,右指针不断向左递减,直到两个指针的值对撞(即left==right)或满足其他要求的特殊条件时结束循环。 适用范围: 解决有序数组或字符串问题:查找有序数组中满足某条件的元素问题(二分查找、数字之和等) 字符串反转问题(反转字符串、回文数、颠倒二进制等问题)

举例说明: 两数之和---给定一个升序排列的数组和一个target值,找到满足相加和为target的两个数,返回它们的下标。 如果是暴力算法,双层for循环,现可改进至单层循环。 (if 两数之和==target,返回下标;if >,right左移;if <,left右移) 验证回文串---给定字符串s,判断是否为回文序列。 (if s[left]==s[right],left右移 right左移;if不等,返回不是回文串;if left==right,返回是回文串)

2.快慢指针

指的是两个指针从数组同一侧开始遍历元素,但两指针以不同的速度、不同的判断条件移动,直到快指针移动到数组尾端,或两指针相交或满足其他特殊条件时结束。 适用范围: 处理数组中的移动、删除元素问题(链表中的判断是否有环、长度问题,还没学)

举例说明: 删除有序数组中的重复项 (slow指向0元素,fast指向1元素;if arr[fsat]!=arr[slow],则slow右移,将fast的元素复制给slow的位置;fast右移;直到fast指向最后元素) (即满足某条件slow才可右移,但满足另一条件或不用满足条件,fast右移)

3.分离双指针

指的是两个指针分属于不同的数组,两个指针分别在两个数组中移动。 适用范围: 处理有序数组合并,求交集、求并集问题。

举例说明: 求两个有序数组的交集 (无序要先排序。两指针left_1,left_2分别指向两数组第0个元素,if arr1[left_1]==arr2[left_2],将该元素添加到新数组中,两指针都右移一;if <,left_1右移;if >,left_2右移;注意答案去重)

二、双指针题目练习

1(344).反转字符串

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left,right;
        char tmp;
        int n=s.size();
        left=0;
        right=n-1;
        do
        {
            tmp=s[left];
            s[left]=s[right];
            s[right]=tmp;
            left+=1;
            right-=1;
        }while(left!=right);

    }

};

//朋友们,这个while里头用==就正常运行,用!=就执行错误,这是咋回事啊!!

2(345).反转字符串中的元音字母

class Solution {
public:
    string reverseVowels(string s) {
        int left,right;
        int n=s.size();
        char tmp;
        int flag=0;
        for(left=0,right=n-1;left==right;left++,right--)
        {
            if(s[left]!='a'&&s[left]!='e'&&s[left]!='o'
            &&s[left]!='u'&&s[left]!='i')
            left++;
            if(s[right]!='a'&&s[right]!='e'&&s[right]!='i'
            &&s[right]!='o'&&s[right]!='u')
            right--;

//cout<<left<<","<<right;
            tmp=s[left];
            s[left]=s[right];
            s[right]=tmp;

            if(left==right)
            break;
        }
        return s;
    }
};

我真服了,咋也不对

3(15).三数之和

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {

        int left,mid,right;
        int n=nums.size();
        int ans[1000][3];
        right=n-1;
        for(left=0;mid==right;left++)
        {
            mid=left+1;
            if(nums[left]+nums[mid]+nums[right]==0)
            {

                mid++;
                continue;}
            mid++;
        }
    }
    return ans[][];
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值