双指针
Posted cxq1126
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双指针相关的知识,希望对你有一定的参考价值。
-
1.数对和
-
2.平方数之和
-
3.颜色分类
-
4.仅仅反转字母
-
5.验证回文字符串II
-
6.最短无序连续子数组
-
7.分发饼干
1.LeetCode面试题 16.24.数对和
设计一个算法,找出数组中两数之和为指定值的所有整数对。一个数只能属于一个数对。
示例 1:
输入: nums = [5,6,5], target = 11
输出: [[5,6]]
示例 2:
输入: nums = [5,6,5,6], target = 11
输出: [[5,6],[5,6]]
1 class Solution: 2 def pairSums(self, nums: List[int], target: int) -> List[List[int]]: 3 nums.sort() 4 res,n=[],len(nums) 5 6 i,j=0,n-1 7 while i<j: 8 if nums[i]+nums[j]<target: 9 i+=1 10 elif nums[i]+nums[j]>target: 11 j-=1 12 else: 13 res.append([nums[i],nums[j]]) 14 i+=1 15 j-=1 16 return res
2.LeetCode 633.平方数之和
给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c。
示例1:
输入: 5
输出: True
解释: 1 * 1 + 2 * 2 = 5
1 class Solution: 2 def judgeSquareSum(self, c: int) -> bool: 3 import math 4 x=math.floor(math.sqrt(c)) 5 i,j=0,x 6 while i<=j: 7 if i**2+j**2<c: 8 i+=1 9 elif i**2+j**2>c: 10 j-=1 11 else: 12 return True 13 return False
3.LeetCode 75.颜色分类
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
1 class Solution: 2 def sortColors(self, nums: List[int]) -> None: 3 """ 4 Do not return anything, modify nums in-place instead. 5 """ 6 i,j,k=0,0,len(nums)-1 #三指针,j前面的全0即红色,j~k全1即白色,k之后的全2即蓝色 7 while j<=k: 8 if nums[j]==0: #j遇到红色,与i位置交换 9 nums[j]=nums[i] 10 nums[i]=0 11 i+=1 12 j+=1 #j交换来的i一定是红色的,所以i和j分别加1 13 elif nums[j]==1: #j遇到白色,直接加1 14 j+=1 15 else: 16 nums[j]=nums[k] #j遇到蓝色,与k位置交换 17 nums[k]=2 18 k-=1
4.LeetCode 917.仅仅反转字母
给定一个字符串 S
,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。
示例 :
输入:"Test1ng-Leet=code-Q!"
输出:"Qedo1ct-eeLg=ntse-T!"
1 class Solution: 2 def reverseOnlyLetters(self, S: str) -> str: 3 j=len(S)-1 4 n,res=len(S),[] 5 6 for i in range(n): 7 if S[i].isalpha(): #i是字母,从j开始往前第一个是字母的字符,添入列表 8 while not S[j].isalpha(): 9 j-=1 10 res.append(S[j]) 11 j-=1 12 else: #i不是字母,将其本身添入列表 13 res.append(S[i]) 14 return ‘‘.join(res)
除了双指针的方法,提供另一种栈的思路
1 class Solution: 2 def reverseOnlyLetters(self, S: str) -> str: 3 lst,res=[],[] #将所有字母字符存入lst 4 for k in S: 5 if k.isalpha(): 6 lst.append(k) 7 8 for x in S: 9 if x.isalpha(): #x是字符,将列表中的最后一位出列,存入res 10 res.append(lst.pop()) 11 else: #x不是字符,将其本身存入res 12 res.append(x) 13 return ‘‘.join(res)
5.LeetCode 680.验证回文字符串II
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
示例 :
输入: "abca"
输出: True
解释: 你可以删除c字符。
1 class Solution: 2 def validPalindrome(self, s: str) -> bool: 3 i,j=0,len(s)-1 4 while i<j: 5 if s[i]!=s[j]: 6 s1=s[:i]+s[i+1:] #舍弃第i位 7 s2=s[:j]+s[j+1:] #舍弃第j位 8 return s1==s1[::-1] or s2==s2[::-1] 9 i+=1 10 j-=1 11 return True
6.LeetCode 581.最短无序连续子数组
给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
你找到的子数组应是最短的,请输出它的长度。
示例 1:
输入: [2, 6, 4, 8, 10, 9, 15]
输出: 5
解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
思路:将数组与排好序的数组比较
1 class Solution: 2 def findUnsortedSubarray(self, nums: List[int]) -> int: 3 tmp=sorted(nums) 4 i,j=0,len(nums)-1 5 while i<j: 6 if tmp[i]==nums[i]: 7 i+=1 8 if tmp[j]==nums[j]: 9 j-=1 10 if tmp[i]!=nums[i] and tmp[j]!=nums[j]: 11 return j-i+1 12 return 0
7.LeetCode 455.分发饼干
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
注意:你可以假设胃口值为正,一个小朋友最多只能拥有一块饼干。
输入: [1,2,3], [1,1]
输出: 1
解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。所以应该输出1。
1 class Solution: 2 def findContentChildren(self, g: List[int], s: List[int]) -> int: 3 g.sort() 4 s.sort() 5 6 peo,bis=len(g),len(s) 7 i,j,count=0,0,0 8 while i<peo and j<bis: 9 if g[i]<=s[j]: 10 count+=1 11 i+=1 12 j+=1 13 else: 14 j+=1 15 return count
以上是关于双指针的主要内容,如果未能解决你的问题,请参考以下文章