【双指针-01】 目录 一、剑指 Offer 57 - II. 和为s的连续正数序列 二、剑指 Offer 57. 和为s的两个数字 三、剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 四、剑指 Offer 53 - II. 0~n-1中缺失的数字 五、剑指 Offer 48. 最长不含重复字符的子字符串/3. 无重复字符的最长子串(滑动窗口) 参考文献

  1. 剑指 Offer 57 - II. 和为s的连续正数序列
  2. 剑指 Offer 57. 和为s的两个数字
  3. 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
  4. 剑指 Offer 53 - II. 0~n-1中缺失的数字
  5. 剑指 Offer 48. 最长不含重复字符的子字符串/3. 无重复字符的最长子串(滑动窗口)

一、剑指 Offer 57 - II. 和为s的连续正数序列

1.1 问题

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例 1

输入:target = 9

输出:[[2,3,4],[4,5]]

示例 2

   

输入:target = 15

输出:[[1,2,3,4,5],[4,5,6],[7,8]]

1.2 思路

双指针,左侧从1开始,且限定在target/2+1,找到一个后,左侧加1滑动。

1.3 代码

class Solution:

def findContinuousSequence(self, target: int) -> List[List[int]]:

i,j,sum,res= 1,1,0,[]

while i <= target//2 +1 :

if sum < target: #小了,加上右侧的数字

sum += j

j += 1

elif sum > target: #大了,减去左侧的数字

sum -= i

i += 1

else: #符合条件,滚动左侧指针

res.append(list(range(i,j)))

sum -= i

i +=1 #这个不能忘记

return res

二、剑指 Offer 57. 和为s的两个数字

2.1 问题

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

示例 1:

输入:nums = [2,7,11,15], target = 9

输出:[2,7] 或者 [7,2]

示例 2:

输入:nums = [10,26,30,31,47,60], target = 40

输出:[10,30] 或者 [30,10]

2.2 代码

class Solution:

def twoSum(self, nums: List[int], target: int) -> List[int]:

i,j = 0,len(nums)-1

while i < j :

s = nums[i] + nums[j]

if s > target:

j -= 1

elif s < target:

i +=1

else:

return nums[i],nums[j]

return []

三、剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

3.1 问题

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

示例:

输入:nums = [1,2,3,4]

输出:[1,3,2,4]

注:[3,1,2,4] 也是正确的答案之一。

3.2 解释

双指针,分四种情况讨论,写的过程中,注意elif的使用。

3.3 代码

class Solution:

    def exchange(self, nums: List[int]) -> List[int]:

        if len(nums)==0 or len(nums) == 1:

            return nums

        i,j = 0 ,len(nums)-1

        while (i<j): #注意分四中情况讨论

            if nums[i] % 2 == 1 and nums[i] % 2 ==1:

                i +=1

            elif nums[j] %2 == 0 and nums[i] %2 ==0:

                j -= 1

            elif nums[i] % 2 ==0 and nums[j] %2 ==1:

                nums[i],nums[j] = nums[j],nums[i]

                i += 1

                j -= 1

            elif nums[i]%2==1 and nums[i]%2==0:

                i += 1

                j -=1

        return nums

四、剑指 Offer 53 - II. 0n-1中缺失的数字

4.1 问题

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0n-1之内。在范围0n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

示例 1:

输入: [0,1,3]

输出: 2

4.2 代码(二分查找)

class Solution:

    def missingNumber(self, nums: List[int]) -> int:

        i , j = 0,len(nums)-1

        while i <= j:    #注意等号

            mid = (i+j)//2  #整除

            if nums[mid] == mid:

                i = mid +1

            else:j = mid -1

        return i   #返回i

五、剑指 Offer 48. 最长不含重复字符的子字符串/3. 无重复字符的最长子串(滑动窗口)

5.1 问题

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

示例 1:

输入: "abcabcbb"

输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3

示例 3:

输入: "pwwkew"

输出: 3

解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3

请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

5.2 代码

class Solution:

    def lengthOfLongestSubstring(self, s: str) -> int:

        if not s :return 0

        max_len = 0

        cur_len =0

        lookup = []

        for right in range(len(s)):

            cur_len += 1

            while s[right]  in lookup:

                lookup.pop(0)

                cur_len -=1

            if cur_len > max_len:max_len = cur_len

            lookup.append(s[right])

        return max_len

参考文献

1https://leetcode-cn.com/