双指针是什么意思,双指针排序

  双指针是什么意思,双指针排序

  1.反向双指针反向式:翻转字符串,判断回文字符串;两个数和型:两个数和,三个数和。

  分区类型:快速排序和颜色排序框架

  Is回文(s): #两个指针(索引),一左一右,从中间向左移动,right=0,len (s)-1 # left必须小于right while left right: if s[left]!=s [right]:返回false left=1 #左移一位右-=1 #右移一位返回True1.1验证回文字符串125。验证回文字符串

  给定一个字符串,验证它是否是回文。只考虑字母和数字字符,字母的大小写可以忽略。

  注意:在本主题中,我们将空字符串定义为有效的回文字符串。

  示例1:

  输入:“一个人,一个计划,一条运河:巴拿马”

  输出:真

  解释:“amanaplanacanalpanama”是一个回文。

  示例2:

  输入:“赛车”

  输出:假

  解释:“raceacar”不是回文。

  1=s.length=2 * 105

  的字符串由ASCII字符组成。

  解决方案:

  类别解决方案:

  def isPalindrome(self,s: str) - bool:

  好=“”。join([I . lower()for I in s if I . is digit()或i.isalpha()])

  左,右=0,len(好)- 1

  而左右:

  如果好[左]!=好[对]:

  返回False

  左=1

  右-=1

  返回True

  1.2验证回文字符串II

  80.验证回文字符串

  给定一个非空字符串s,最多删除一个字符。判断它是否能成为回文字符串。

  示例1:

  输入:s=aba

  输出:真

  示例2:

  输入:s=abca

  输出:真

  说明:可以删除C字符。

  示例3:

  输入:s=abc

  输出:假

  1=标准长度=105

  s由小写英文字母组成。

  解决方案:

  类别解决方案:

  def有效回文(self,s: str) - bool:

  如果len(s)==1:

  返回True

  l,r=0,len(s) - 1

  而l r:

  如果s[l]==s[r]:

  l=1

  r -=1

  否则:

  返回self . is _回文(s,l 1,r)或self . is _回文(s,l,r-1)

  返回True

  def是_回文(self,s,l,r):

  而l r:

  如果s[l]!=s[r]:

  返回False

  l=1

  r -=1

  返回True

  1.3两个数之和

  1.两个数的和

  给定一个整数数组nums和一个整数目标值target,请找出数组中作为目标值的两个整数,并返回它们的数组下标。

  你可以假设每个输入只对应一个答案。但是,数组中的同一个元素不能在答案中重复。

  您可以按任意顺序返回答案。

  示例1:

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

  输出:[0,1]

  说明:因为nums[0] nums[1]==9,所以返回[0,1]。

  示例2:

  输入:nums=[3,2,4],目标=6

  输出:[1,2]

  示例3:

  输入:nums=[3,3],目标=6

  输出:[0,1]

  2=nums.length=104

  -109=nums[i]=109

  -109=目标=109

  只有一个有效的答案。

  问题1:哈希表(时间和空间复杂度为O(n))

  类别解决方案:

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

  信息={}

  对于索引,我在枚举(nums):

  如果目标- i在信息中:

  返回[信息[目标-i],索引]

  如果我不在信息中:

  信息[i]=索引

  return [-1,-1]

  解决方案2:排序双指针(时间复杂度O(nlogn),空间复杂度O(1))

  类别解决方案:

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

  num_idx=[(num,i) for i,num in enumerate(nums)]

  num _ idx . sort(key=lambda x:x[0])#[(2,0),(7,1),(11,2),(15,3)]

  left,right=0,len(nums) - 1

  而左右:

  if num _ idx[left][0]num _ idx[right][0]==target:

  return[数字索引[左][1],数字索引[右][1]]

  elif num _ idx[left][0]num _ idx[right][0]target:

  右-=1

  否则:

  左=1

  return [-1,-1]

  1.4二分搜索法

  74.二进位检索

  给定一个整数数组nums,有n个有序元素和一个目标值target,写一个函数在nums中搜索目标,如果目标值有返回下标,返回-1,否则返回。

  示例1:

  输入:nums=[-1,0,3,5,9,12],目标=9

  输出:4

  解释:9出现在nums中,它的下标是4

  示例2:

  输入:nums=[-1,0,3,5,9,12],目标=2

  输出:-1

  说明:2在nums中不存在,所以返回-1。

  您可以假设num中的所有元素都不是重复的。

  n将介于[1,10000]之间。

  nums的每个元素都会在[-9999,9999]之间。

  解决方案:

  类别解决方案:

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

  left,right=0,len(nums) - 1

  而左=右:

  mid=(左右)//2

  if nums[mid]==目标:

  返回mid

  elif nums[mid]目标:

  右-=1

  否则:

  左=1

  返回-1

  1.5反向排列

  从输入导入列表

  类别解决方案:

  def reverse_list(self,nums: List[str]) - List[str]:

  left,right=0,len(nums) - 1

  而左右:

  temp=nums[left]

  Nums[left]=nums[right] #交换两个数。

  nums[right]=温度

  右-=1

  左=1

  返回数字

  if __name__==__main__ :

  s=解决方案()

  print(s.reverse_list([1 , 2 , 3]))

  print(s.reverse_list([3 , 2 , 1]))

  分析:

  nums=[1 , 2 , 3]

  #第一次

  左=0,右=2

  当0 2:

  temp=1

  nums[0]=nums[2]=nums=[3 , 2 , 3]

  nums[2]=1=nums=[3 , 2 , 1]

  右-=1

  左=1

  #第二次

  左=1,右=1

  而1 1:

  返回数字

  1.6判断字符串回文

  定义解决方案(字符串):

  left,right=0,len(string) - 1

  而左右:

  if字符串[left]!=string[right]:

  返回False

  左=1

  右-=1

  返回True

  if __name__==__main__ :

  打印(解决方案( aba ))

  打印(解决方案( abac ))

  打印(解决方案( 1221 ))

  2.回到双指针

  2.1最长的回文子串

  5.最长的回文子串

  给你一个字符串S,求S中最长的回文子串。

  示例1:

  Enter: s=babad

  输出:“bab”

  说明:‘ABA’也是问题的答案。

  示例2:

  输入:s=cbbd

  解决方案:

  技能:由中心向两端扩散的两分球技能。

  因为回文串长度可能是奇数也可能是偶数;如果是奇数,可以中间字符为分界点向两端扩散;如果是偶数,中心两个字符可以向外扩散:

  类别解决方案:

  def longest回文(self,s: str) - str:

  long_sub=

  对于范围内的I(透镜):

  S1=is _回文(s,I,i) #以s[i]为中心的最长回文子串

  S2=is _回文(s,I,i 1) #以s[i]和s[i 1]为中心的最长回文子串

  long _ sub=long _ sub if len(long _ sub)len(S1)else S1

  long _ sub=long _ sub if len(long _ sub)len(S2)else S2

  返回long_sub

  def is _回文(s,l,r):

  寻找s中以s[l]和s[r]为中心的最长回文字符串

  #防止下标越界

  当l=0和r len(s)时:

  如果s[l]!=s[r]:

  破裂

  #双手向两边展开

  l -=1

  r=1

  Return s[l 1: r] #返回以s[l]和s[r]为中心的最长的回文字符串

  3.同一个方向的双指针

  同向双指针又叫快慢指针。

  3.1删除有序数组副本

  26.删除有序数组中的重复项。

  给你一个升序排列的数组nums,请把重复的元素删除到位,让每个元素只出现一次,并返回被删除数组的新长度。元素的相对顺序应该一致。

  因为在某些语言中数组的长度不能改变,所以结果必须放在数组nums的第一部分。更具体地说,如果删除重复项后有k个元素,那么nums的前k个元素应该保存最终结果。

  将最终结果插入nums的前k个位置,并返回k。

  不是使用额外的空间,而是必须就地修改输入数组,并用O(1)个额外的空间来完成它。

  示例1:

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

  输出:2,nums=[1,2,_]

  说明:函数应该返回新的长度2,原数组nums的前两个元素修改为1,2。不需要考虑数组中超出新长度的元素。

  示例2:

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

  输出:5,nums=[0,1,2,3,4]

  说明:函数应该返回新的长度5,原数组nums的前五个元素修改为0,1,2,3,4。不需要考虑数组中超出新长度的元素。

  解决方案:

  从输入导入列表

  类别解决方案:

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

  如果len(nums)==0:

  返回0

  慢,快=0,0

  打印(数字、慢速、快速)

  而快速len(nums):

  if nums[快]!=nums[慢速]:

  慢速=1

  nums[慢速]

  快速=1

  打印(数字、慢速、快速)

  慢速返回1

  if __name__==__main__ :

  s=解决方案()

  print(s.removeDuplicates([1,1,2,3])# 3

  print(s.removeDuplicates([0,0,1,1,2,3,4,5,6])# 7

  [1, 1, 2, 3] 0 0

  [1, 1, 2, 3] 0 1

  [1, 1, 2, 3] 0 2

  [1, 2, 2, 3] 1 3

  [1, 2, 3, 3] 2 4

  慢指针走在后面,快指针走在前面,遇到非重复元素会赋给慢,慢向前一步,这样nums[0,slow]就是非重复元素。

  3.2删除排序链表中的重复元素

  83.删除排序链表中的重复元素。

  给定一个有序链表的头,删除所有重复的元素,这样每个元素只出现一次。返回排序后的链表。

  输入:head=[1,1,2]

  输出:[1,2]

  输入:head=[1,1,2,3,3]

  输出:[1,2,3]

  解决方案:

  #单链表的定义。

  #类别列表节点:

  # def __init__(self,val=0,next=None):

  # self.val=val

  # self.next=下一个

  类别解决方案:

  def deleteDuplicates(self,head: ListNode) - ListNode:

  如果head==None:

  不返回

  慢=快=头

  一边快!=无:

  如果快.瓦尔!=slow.val:

  slow.next=fast

  慢=慢。下一个

  快=快。下一个

  Slow.next=None #断开下列重复元素。

  回程头

  3.3从数组中删除指定的元素。

  27.移除元素

  给定一个数组nums和值val,您需要就地移除值等于val的所有元素,并返回移除后数组的新长度。

  您不必使用额外的数组空间,只需使用O(1)个额外的空间,并就地修改输入数组。

  元素的顺序可以改变。不需要考虑数组中超过新长度的元素。

  示例1:

  输入:nums=[3,2,2,3],val=3

  输出:2,nums=[2,2]

  说明:函数应该返回新的长度2,nums中的前两个元素都是2。不需要考虑数组中超过新长度的元素。比如函数返回的新长度是2,nums=[2,2,3,3]或者nums=[2,2,0,0]也会被视为正确答案。

  示例2:

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

  输出:5,nums=[0,1,4,0,3]

  说明:函数应该返回新的长度5,nums中的前五个元素是0,1,3,0,4。请注意,这五个元素可以按任意顺序排列。不需要考虑数组中超过新长度的元素。

  解决方案:

  从输入导入列表

  类别解决方案:

  def removeElement(self,nums: List[int],val: int) - int:

  如果不是nums:

  返回0

  慢,快=0,0

  print(f nums:{ nums } \ t slow:{ slow } \ t fast:{ fast } \ t val:{ val } )

  而快速len(nums):

  if nums[快]!=val:

  nums[慢速]

  慢速=1

  快速=1

  print(f nums:{ nums } \ t slow:{ slow } \ t fast:{ fast } \ t val:{ val } )

  缓慢返回

  if __name__==__main__ :

  s=解决方案()

  # print(s.removeElement([0,1,2,2,3,0,4,2],2))

  print(s.removeElement([0,1,2),0)) # 2

  数字:[0,1,2]慢:0快:0值:0

  数字:[0,1,2]慢:0快:1值:0

  nums: [1,1,2]慢:1快:2值:0

  nums: [1,2,2]慢:2快:3值:0

  如果fast的元素与val相同,它将被跳过,fast 1

  当fast的元素不同于val时,将当前元素指定为slow,slow前进1。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: