一、复习链表题目:
1.leetcode题目 141环形链表(easy):
直接用快慢指针法,集合法很简单就不写了。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
if not head or not head.next:
return False
slow = head
fast = head.next
while fast and fast.next:
if slow== fast:
return True
fast = fast.next.next
slow = slow.next
return False
2. leetcode题目 21.合并两个有序链表(easy):
题目描述:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
解决:①迭代法:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
cur1 = list1
cur2 = list2
cur3 = ListNode(0)
cur = cur3
while cur1 and cur2:
if cur1.val <= cur2.val:
cur.next = cur1
cur1 = cur1.next
else:
cur.next = cur2
cur2 = cur2.next
cur = cur.next
cur.next = cur1 if cur1 is not None else cur2
return cur3.next
②递归法:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
cur1 = list1
cur2 = list2
if not cur1:
return cur2
if not cur2:
return cur1
while cur1 and cur2:
if cur1.val<=cur2.val:
cur1.next = self.mergeTwoLists(cur1.next,cur2)
return cur1
else:
cur2.next = self.mergeTwoLists(cur1,cur2.next)
return cur2
二、哈希表:
1.leetcode题目 242 有效的字母异位词(easy)
题目描述:
给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的字母异位词。
注意:若 s
和 t
中每个字符出现的次数都相同,则称 s
和 t
互为字母异位词。
解决:
①dictionary:
(我这个方法吧 跟官方题解还不太一样)
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
res = {}
m = len(s)
n = len(t)
if m != n:
return False
for i in s:
if i not in res:
res[i] = 0
res[i] += 1
for j in t:
if j not in res:
return False
else:
res[j] -= 1
if res[j] == 0:
del res[j]
return True
②python中 直接计数:(内存和时间消耗比第一种方法大)
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if Counter(s) == Counter(t):
return True
else:
return False
③用defaultdict函数(方法一的简化版):
from collections import defaultdict
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
s_d = defaultdict(int)
t_d = defaultdict(int)
for i in s:
s_d[i] += 1
for j in t:
t_d[j] += 1
return s_d== t_d
2.leetcode题目 赎金信(easy)
题目描述:
给你两个字符串:ransomNote
和 magazine
,判断 ransomNote
能不能由 magazine
里面的字符构成。
如果可以,返回 true
;否则返回 false
。
magazine
中的每个字符只能在 ransomNote
中使用一次。
解决:
①偷懒用defaltdict:
from collections import defaultdict
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
r_dict = defaultdict(int)
m_dict = defaultdict(int)
if len(ransomNote) > len(magazine):
return False
else:
for i in ransomNote:
r_dict[i] += 1
for j in magazine:
m_dict[j] += 1
if all(i in r_dict and m_dict[i]>=r_dict[i] for i in r_dict):
return True
else:
return False
3.leetcode题目 49 字母异位词分组(medium):
题目描述:
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
个人思路(计数):
解决:
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
dic = collections.defaultdict(list)
s = []
for string in strs:
record = [0]*26
for i in string:
record[ord(i) - ord('a')] += 1
record = tuple(record)
dic[record].append(string)
output = []
for i in dic:
output.append(dic[i])
##后面这个for循环可以替换成list(dic.values())
return output
之前有过的思路:排序。 但是我当时不知道给字符串排序的函数(在这里不得不感叹一句collections.dafaultdict真牛):
解决:
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
dic = collections.defaultdict(list)
s = []
for string in strs:
i = "".join(sorted(string))
dic[i].append(string)
return list(dic.values())
4.leetcode题目 438找到字符串中所有字母异位词(medium):
思路:滑窗
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
record_p = [0]*26
for i in p :
record_p[ord(i) - ord('a')] += 1
slow = 0
fast = 0
l = []
n = len(s)
record_s = [0]*26
for fast in range(n):
record_s[ord(s[fast]) -ord('a') ] += 1
while record_s[ord(s[fast]) -ord('a') ]>record_p[ord(s[fast]) -ord('a') ]:
record_s[ord(s[slow]) -ord('a')] -= 1
slow += 1
if record_s == record_p:
l.append(slow)
return l
5.leetcode题目 349.两个数组的交集(easy):
题目描述:给定两个数组 nums1
和 nums2
,返回 它们的 交集。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
解决:
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
res = set()
l = set()
for i in nums1:
res.add(i)
for j in nums2:
if j in res and j not in l:
l.add(j)
return list(l)
6.leetcode题目 350.两个数组的交集II(easy):
题目描述:给你两个整数数组 nums1
和 nums2
,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
解决:排序后双指针
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
nums1.sort()
nums2.sort()
index1 = 0
index2 = 0
l = list()
while index1<len(nums1) and index2<len(nums2):
if nums1[index1] < nums2[index2]:
index1 += 1
elif nums1[index1] > nums2[index2]:
index2 += 1
else:
l.append(nums1[index1])
index1 += 1
index2 += 1
return l
7.leetcode题目 202 快乐数(easy):
题目描述:
编写一个算法来判断一个数 n
是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n
是 快乐数 就返回 true
;不是,则返回 false
。
思路:(这题没啥思路,看了题解)
解决:
def isHappy(self, n: int) -> bool:
def get_next(number):
total_sum = 0
while number > 0:
number, digit = divmod(number, 10)
total_sum += digit ** 2
return total_sum
slow_runner = n
fast_runner = get_next(n)
while fast_runner != 1 and slow_runner != fast_runner:
slow_runner = get_next(slow_runner)
fast_runner = get_next(get_next(fast_runner))
return fast_runner == 1
8.leetcode题目 1.两数之和(easy):
题目描述:
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
解决:
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
records = dict()
for i,num in enumerate(nums):
if target-num in records:
return [records[target-num],i]
records[nums[i]] = i
return []
三、总结:
1.需要进脑子的知识:
①字母转数字用ord
②collections.defaultdict用法
③all()以及any()的用法
④字符串排序用sorted(string)
⑤明天重新看202 快乐数这道题