力扣 双指针专题

167. 两数之和 II

https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/

 vector<int> twoSum(vector<int>& numbers, int target) {
        for(int i=0,j=numbers.size()-1;i<j;i++){
            while(i<j && numbers[i]+numbers[j]>target) j--;
            if(i<j && numbers[i]+numbers[j]==target) return {i+1,j+1};
        }
        return {};
    }

思路:定义双指针,i在数组的开头,j在数组的末尾。
如果两个指针指向元素的和 sum == target,那么得到要求的结果;
如果 sum > target,移动较大的元素,使 sum 变小一些;
如果 sum < target,移动较小的元素,使 sum 变大一些。
数组中的元素最多遍历一次,时间复杂度为 O(N)。只使用了两个额外变量,空间复杂度为 O(1)。

633. 平方数之和

https://leetcode-cn.com/problems/sum-of-square-numbers/submissions/

bool judgeSquareSum(int c) {
        for(long long i=0;i*i<=c;i++){
            int j=c-i*i;
            int r=sqrt(j);
            if(r*r==j){
                return true;
            }
        }
        return false;
    }

直接暴力完事。 也可以用上题的思路,稍微转换一下就可

class Solution {
public:
    bool judgeSquareSum(int c) {
        for(long long i=0,j=sqrt(c);i<=j;i++){
            while(i<=j && i*i+j*j >c) j--;
            if(i<=j && i*i+j*j==c) return true;
        }
        return false;
    }
};

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

头尾开始循环,都找到就交换即可

class Solution {
public:
    string s="aeiou";
	bool isyuan(char c){
		return s.find(tolower(c))!=-1;
	}
	string reverseVowels(string s) {
        for(int i=0,j=s.size()-1;i<j;i++,j--){
            while(i<j && !isyuan(s[i]))i++;
            while(i<j && !isyuan(s[j]))j--;
            swap(s[i],s[j]);
        }
        return s;
    }
};

680. 验证回文字符串 Ⅱ

https://leetcode-cn.com/problems/valid-palindrome-ii/description/

class Solution {
public:
    bool validPalindrome(string s) {
        for (int i = 0, j = s.size() - 1;i < j;i++, j--) {
            if (s[i] != s[j]) {
                return(fun(i + 1, j, s) || fun(i, j - 1, s));
                }
            }
    return true;
    }
    bool fun(int i, int j,string s) {
        while (i < j) {
            if (s[i] != s[j]) {
                return false;
            }
            i++;j--;
        }
        return true;
    }
};

本题的关键是处理删除一个字符。在使用双指针遍历字符串时,如果出现两个指针指向的字符不相等的情况,我们就试着删除一个字符,再判断删除完之后的字符串是否是回文字符串。

在判断是否为回文字符串时,我们不需要判断整个字符串,因为左指针左边和右指针右边的字符之前已经判断过具有对称性质,所以只需要判断中间的子字符串即可。

在试着删除字符时,我们既可以删除左指针指向的字符,也可以删除右指针指向的字符。

88. 合并两个有序数组

https://leetcode-cn.com/problems/merge-sorted-array/

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
            int k=m+n-1;//确定开始下标
            int i=m-1,j=n-1;//确定两个数组指针下标
            while(i>=0 && j>=0){
                if(nums1[i]>=nums2[j]){
                    nums1[k--]=nums1[i--];
                } 
                else nums1[k--]=nums2[j--];
            }
            while(j>=0){
                nums1[k--]=nums2[j--];
            }

    }
};

两个有序数组合并,但是题目比较特殊需要结果合并到第一个数组,这里通过反向合并即可解决问题。

141. 环形链表

https://leetcode-cn.com/problems/linked-list-cycle/

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null) return false;
        ListNode l1=head;
        ListNode l2=head.next;
        while(l1 != null && l2 != null && l2.next!=null){
            if(l1==l2) return true;
            l1=l1.next;//每次走一步
            l2=l2.next.next;//每次走两步
        }
        return false;
    }
}

经典快慢指针判断环算法(java语言)

524. 通过删除字母匹配到字典里最长单词

class Solution {
public:
    bool check(string& a, string& b) {
        int i=0, j = 0;
        while (i < a.size() && j < b.size()) {
            if (a[i] == b[j]) {
                i++;
            }
            j++;
            if (i == a.size() ) {
                return true;
            }
        }
        return false;
    }
    string findLongestWord(string s, vector<string>& d) {
        string res;
        for (auto str : d) {
            if (check(str, s)) {
                if (res.empty() == true || res.size()<str.size() || res.size()==str.size() && res>str) {
                    res = str;
                }
            }
        }
        return res;
    }
};

通过双指针实现一个判断是否是子序列函数

之后每次循环字符串集,如果是子序列就判断和之前保存的答案哪个是最优解

posted @ 2021-02-17 14:56  一个经常掉线的人  阅读(78)  评论(0)    收藏  举报