LeetCode | 双指针

Posted KAI-yq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode | 双指针相关的知识,希望对你有一定的参考价值。

目录

3.2 167. 两数之和 II 输入有序数组

给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。

函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。

你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

示例 1:

输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

代码:

class Solution 
public:
    vector<int> twoSum(vector<int>& numbers, int target) 
        int l=0,r=numbers.size()-1,sum;
        while(l<r)
            sum=numbers[l]+numbers[r];
            if(sum==target) break;
            if(sum>target) --r;
            else ++l;
        
        return vector<int>l+1,r+1;

    
;

一些注意点

vector<int> twoSum(vector<int>& numbers, int target)


这里twoSum是一个vector<int>类型的函数,同时返回值也是vector<int>型
如:return vector<int>l+1,r+1;
这里注意vector<int>l+1,r+1用的是

int l=0,r=numbers.size()-1,sum;这里第一次sum前的,写成了;
注意int一次可初始化几个参数,用,隔开,且可以有初值也可以没有

if(sum>target) --r;
else ++l;
注意ifelse的用法,++l,--r是返回运算后的,反之返回运算前的

3.5 88. 合并两个有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

示例 1:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]

代码:

class Solution 
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) 
        int pos = m-- + n-- -1;
        while(m>=0 && n>=0)
            nums1[pos--]=nums1[m]>nums2[n] ? nums1[m--] : nums2[n--];
        
        while(n>=0)
            nums1[pos--] = nums2[n--];
        
    
;

一些注意点

详细练了n–,m–返回n,m
数组起始值为0,即判断条件为>=0,因为可以等于0
用了三个指针,两个指针搜索,第三个指针直接用索引赋值

3.10 142.环形链表

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

示例 :

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode 
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) 
 * ;
 */
class Solution 
public:
    ListNode *detectCycle(ListNode *head) 
        ListNode *fast=head,*slow=head;
        do
            if(!fast||!fast->next) return NULL;
            fast=fast->next->next;
            slow=slow->next;
        while(slow!=fast);
        fast=head;
        while(slow!=fast)
            fast=fast->next;
            slow=slow->next;
        
        return fast;
        
    
;

一些注意点

第一个do…while里while的判断为while(fast!=slow)

3.16 76.最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。
注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”

代码:

class Solution 
public:
    string minWindow(string s, string t) 
        vector<int> chars(128,0);
        vector<bool> flag(128,false);

        //先统计T中字符的情况
        for(int i=0;i<t.size();++i)
            flag[t[i]]=true;
            ++chars[t[i]];
        
        
        //移动滑动窗口
        int cnt=0 , l=0 , min_l=0 , min_size=s.size()+1;
        for(int r=0;r<s.size();r++)
            if(flag[s[r]])
                if(--chars[s[r]]>=0)
                    ++cnt;
                

                //若目前滑动窗口已包含T中全部字符
                //则尝试右移l
                while(cnt==t.size())
                    if(r-l+1<min_size)
                        min_l=l;
                        min_size=r-l+1;
                    
                    if(flag[s[l]]&&++chars[s[l]]>0)
                        --cnt;
                    
                    ++l;
                
            
        
        return min_size>s.size()?"":s.substr(min_l,min_size);

    
;

4.3 反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

迭代

class Solution 
public:
    ListNode* reverseList(ListNode* head) 
        ListNode *prev = nullptr , *curr = head , *next ; 
        while(curr != nullptr)
            next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        
    return prev;
    
;

递归

class Solution 
public:
    ListNode* reverseList(ListNode* head) 
        if(head == nullptr || head->next == nullptr)
            return head;
        
        ListNode* p = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return p;
    
;

注意点:
链表定义加* , 如ListNode* p;
指向下一个节点用 ->
空指针是 nullptr

以上是关于LeetCode | 双指针的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode日记——算法双指针专题

双指针 - 两数之和 & 两数平方和

Leetcode刷题100天—167. 两数之和 II - 输入有序数组(双指针)—day20

Leetcode刷题100天—167. 两数之和 II - 输入有序数组(双指针)—day20

LeetCode小白算法成长记之双指针

数据结构与算法双指针思想——两数之和