leetcode 15 三数之和
本题要求三数之和,难度一下子比两数之和提升不少。除了要找出符合条件的数组以外还要避免重复。主要思路:
- 先固定一个值,再利用双指针找另外两个
- 想要合理利用双指针,就需要对原数组进行从小到大排序,将双指针分别放在起始点后面那半数组的头和尾上
- 利用排完序的特性,每次将三个数之和与目标值比较,大于目标值则移动右指针;小于则移动左指针
- 在找数的过程中去重,只有在找到符合条件的数组时才需要考虑重复的情况,另外也要考虑固定值的重复情况
- 优化:当固定值大于0时,后面必然不会再有符合条件的组合了,直接跳出
class Solution: def isLongPressedName(self, name: str, typed: str) -> bool: if len(name) > len(typed): return False j = 0 for i in range(len(name)): if name[i] != typed[j]: return False else: if j < len(typed)-1: #注意j的边界 j += 1 if i < len(name)-1 and name[i] != name[i+1]: while j > 0 and j < len(typed)-1 and typed[j] == typed[j-1]: # 注意j的边界 j += 1 for i in range(j,len(typed)): # 注意当name遍历完但是typed还有多余非重复字符时的情况 if typed[i] != name[-1]: return False return True
leetcode 925 长按键入
此题遍历比较即可,需要注意的点是当name里本身有重复字符的时候如何处理,这里给出两种办法:
- 第一种以name为基准,当typed中有重复字符时while跳过,除非name中下一个字符与当前字符相等,则不必跳过typed中的重复字符,直接给索引加一,直到遍历完name。此时需要另外考虑一种情况,即typed结尾有非重复的多余字符。
class Solution: def isLongPressedName(self, name: str, typed: str) -> bool: if len(name) > len(typed): return False j = 0 for i in range(len(name)): if name[i] != typed[j]: # 如当前字符不相等,直接跳出 return False else: if j < len(typed)-1: #注意j的边界 j += 1 if i < len(name)-1 and name[i] != name[i+1]: while j > 0 and j < len(typed)-1 and typed[j] == typed[j-1]: # 注意j的边界 j += 1 for i in range(j,len(typed)): # 注意当name遍历完但是typed还有多余非重复字符时的情况 if typed[i] != name[-1]: return False return True
- 另一种方法比较简洁,以typed为基准遍历,每次都同时移动两个指针,判断两个字符是否相等,如果不等,则说明有长按键入,那么只将typed遍历索引加一,最后判断name是否遍历完
class Solution: def isLongPressedName(self, name: str, typed: str) -> bool: # 定义指针,分别指向 name 和 typed 的首字符 n = 0 t = 0 # 遍历 typed 与 name 中的字符比较 while t < len(typed): # 比较,相同移动指针 if n < len(name) and name[n] == typed[t]: n += 1 t += 1 # 不相同时,要注意 p 指针指向的元素 # 如果是首元素,那么表示 name 和 typed 首字符都不同,可以直接返回 False # 如果不在首元素,看是否键入重复,键入重复,继续移动 q 指针,继续判断;如果不重复,也就是不相等的情况,直接返回 False,表示输入错误 elif n > 0 and name[n-1] == typed[t]: t += 1 else: return False # typed 遍历完成后要检查 name 是否遍历完成 return n == len(name)