python--双指针
双指针yyds
双指针: 即用两个不同速度或不同方向的指针对列表进行访问,通过两个不同指针的碰撞从而达到特定的目的。
为节省时间和空间,利用单次遍历,判断指针碰撞实现问题的解。
根据双指针定义,可划分三类
-
- 快慢双指针
- 左右双指针
- 滑动窗口
1、快慢双指针:前后双指针,以不同的移动速度遍历
- 判断数组或链表的长度
- 是否有环
- 特定位置的值,比如列表的中间元素
案例:链表的中间结点--给定一个头结点为 head 的非空单链表,返回链表的中间结点。
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。
def middleNode(self, head): """ :type head: ListNode :rtype: ListNode """ slow = fast = head while fast and fast.next: slow = slow.next fast = fast.next.next return slow
案例:删除有序数组中的重复项
给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
输入: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): """ :type nums: List[int] :rtype: int """ if len(nums)<=1: return len(nums) left=0 right=1 while right<len(nums) : if nums[left]==nums[right]: right +=1 else: left +=1 nums[left]=nums[right] right +=1 return left+1
2、左右双指针:左右指针分别从列表两端移动
- 快速排序
- 倒置
案例:给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
输入:s = " hello world "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。
输入:s = "a good example"
输出:"example good a"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。


class Solution(object): def trimSpace(self,s): outPut = [] outPut.append(" ") for i in range(len(s)): outPut.append(s[i]) outPut.append(" ") return outPut def reverseAll(self,s): left = 0 right = len(s) - 1 while left < right: temp = s[left] s[left] = s[right] s[right] = temp left += 1 right -= 1 return s def reverseWords(self, s): """ :type s: str :rtype: str """ s=self.trimSpace(s) s=self.reverseAll(s) left = 0 right = 0 i=0 n = len(s) t=[] while right < n: if s[right] == " ": res = self.reverseAll(s[left:right]) t.extend(res) t.append(" ") right += 1 left = right right += 1 else: right += 1 while t[0] == " ": del t[0] while t[-1]==" ": del t[-1] output = [] i, j = 0, len(t) - 1 while i <= j: if t[i] != ' ': output.append(t[i]) elif output[-1] != ' ': output.append(t[i]) i += 1 return ''.join(output)
3、滑动窗口:有左右端点和长度,根据要求调整窗口
- 无重复字符的最长子串
案例:无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

def lengthOfLongestSubstring(self, s): """ :type s: str :rtype: int """ left = 0 maxSubset = 0 subset = [] right = 0 while right < len(s): if s[right] not in subset: subset.append(s[right]) right += 1 maxSubset = max(maxSubset, len(subset)) else: del subset[left] #注意:因为每次删除的是头部,删除后还是定位在头部,就不需要处理left return maxSubset

浙公网安备 33010602011771号