classSolution: defisAnagram(self, s: str, t: str) -> bool: ls, lt = len(s), len(t) if ls != lt: returnFalse h = {} for i inrange(ls): if s[i] in h: h[s[i]] += 1 else: h[s[i]] = 1 for i inrange(lt): if t[i] in h: h[t[i]] -= 1 if h[t[i]] < 0: returnFalse else: returnFalse returnTrue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution: defisAnagram(self, s: str, t: str) -> bool: ls, lt = len(s), len(t) if ls != lt: returnFalse h = defaultdict(int) for i inrange(ls): h[s[i]] += 1 for i inrange(lt): h[t[i]] -= 1 if h[t[i]] < 0: returnFalse for i in h.values(): if i != 0: returnFalse returnTrue
Go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//使用数组
funcisAnagram(s, t string)bool { iflen(s) != len(t) { returnfalse } var c1, c2 [26]int for _, ch := range s { c1[ch-'a']++ } for _, ch := range t { c2[ch-'a']++ } return c1 == c2 }
1 2 3 4 5 6 7 8 9 10 11
//t 是 s的异位词等价于「两个字符串排序后相等」。因此我们可以对字符串 s 和 t 分别排序,看排序后的字符串是否相等即可判断。此外,如果 s 和 t 的长度不同,t 必然不是 s 的异位词。
funcisAnagram(s string, t string)bool { iflen(s) != len(t) { returnfalse } h := make(map[rune]int) for _, char := range s { h[char]++ } for _, char := range t { h[char]-- if h[char] < 0 { returnfalse } } returntrue }
classSolution: defintersection(self, nums1: List[int], nums2: List[int]) -> List[int]: returnlist(set([x for x in nums1 if x in nums2]))
1 2 3 4 5
classSolution: defintersection(self, nums1: List[int], nums2: List[int]) -> List[int]: nums1 = set(nums1) nums2 = set(nums2) return [x for x in nums1 if x in nums2]
1 2 3 4
classSolution: defintersection(self, nums1: List[int], nums2: List[int]) -> List[int]: nums1=set(nums1) return [x for x in nums1 if x in nums2]
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defintersection(self, nums1: List[int], nums2: List[int]) -> List[int]: vis = {} out = [] for i in nums1: vis[i] = False for i in nums2: if i in vis: vis[i] = True for k, v in vis.items(): if v: out.append(k) return out
Go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
funcintersection(nums1 []int, nums2 []int) []int { vis := make(map[int]bool) out := make([]int, 0) for _, i := range nums1 { vis[i] = false } for _, i := range nums2 { if _, ok := vis[i]; ok { vis[i] = true } } for k, v := range vis { if v == true { out = append(out, k) } } return out }
# 哈希表 classSolution: defisHappy(self, n: int) -> bool: seen = set() while n != 1and n notin seen: seen.add(n) n = self.get_sum(n) return n == 1
defget_sum(self, n: int): _sum = 0 while n > 0: n, digit = divmod(n, 10) _sum += digit**2 return _sum
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 双指针法 classSolution: defisHappy(self, n: int) -> bool: defstep(num): _sum = 0 while num > 0: num, digit = divmod(num, 10) _sum += digit**2 return _sum slow, fast = n, step(n) while fast != 1and slow != fast: slow = step(slow) fast = step(step(fast)) return fast == 1
Go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//哈希表 funcisHappy(n int)bool { seen := make(map[int]bool) for ; n != 1 && !seen[n]; n, seen[n] = getSum(n), true { } return n == 1 }
funcgetSum(n int) (sum int) { for n > 0 { sum += (n % 10) * (n % 10) n /= 10 } return sum }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
//双指针法 funcisHappy(n int)bool { slow, fast := n, step(n) for fast != 1 && slow != fast { slow = step(slow) fast = step(step(fast)) } return fast == 1 }
funcstep(n int)int { sum := 0 for n > 0 { sum += (n%10) * (n%10) n = n/10 } return sum }
#暴力解法 classSolution: deftwoSum(self, nums: List[int], target: int) -> List[int]: n = len(nums) for i inrange(n): for j inrange(i + 1, n): if nums[i] + nums[j] == target: return [i, j] return []
1 2 3 4 5 6 7 8 9
#哈希表 classSolution: deftwoSum(self, nums: List[int], target: int) -> List[int]: hashtable = dict() for i, num inenumerate(nums): if target - num in hashtable: return [hashtable[target - num], i] hashtable[nums[i]] = i return []
Go:
1 2 3 4 5 6 7 8 9 10 11
//暴力解法 functwoSum(nums []int, target int) []int { for i, x := range nums { for j := i + 1; j < len(nums); j++ { if x+nums[j] == target { return []int{i, j} } } } returnnil }
1 2 3 4 5 6 7 8 9 10 11
//哈希表 functwoSum(nums []int, target int) []int { hashTable := map[int]int{} for i, x := range nums { if p, ok := hashTable[target-x]; ok { return []int{p, i} } hashTable[x] = i } returnnil }
classSolution: deffourSumCount( self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int] ) -> int: count = 0 sum_count = defaultdict(int) for i in nums1: for j in nums2: sum_count[i + j] += 1 for i in nums3: for j in nums4: count += sum_count[-(i + j)] return count #四数求和问题一个最常用的优化方法是通过降低复杂度,但这也取决于具体问题的需求。最直接的方法,即四个数组的四次循环,其时间复杂度为O(n^4)。以上述方法通过两次双重循环和哈希表降低了时间复杂度到O(n^2)。
1 2 3 4 5 6 7 8 9
classSolution: deffourSumCount(self, A: List[int], B: List[int], C: List[int], D: List[int]) -> int: countAB = collections.Counter(u + v for u in A for v in B) ans = 0 for u in C: for v in D: if -u - v in countAB: ans += countAB[-u - v] return ans
Go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
funcfourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int)int { sumCount := make(map[int]int) count := 0 for _, num1 := range nums1 { for _, num2 := range nums2 { sumCount[num1+num2]++ } } for _, num3 := range nums3 { for _, num4 := range nums4 { count += sumCount[-(num3 + num4)] } } return count } //四数求和问题一个最常用的优化方法是通过降低复杂度,但这也取决于具体问题的需求。最直接的方法,即四个数组的四次循环,其时间复杂度为O(n^4)。以上述方法通过两次双重循环和哈希表降低了时间复杂度到O(n^2)。
#数组,速度最快 classSolution: defcanConstruct(self, ransomNote: str, magazine: str) -> bool: iflen(ransomNote) > len(magazine): returnFalse cnt = [0] * 26 for i in magazine: cnt[ord(i) - ord("a")] += 1 for i in ransomNote: t = ord(i) - ord("a") cnt[t] -= 1 if cnt[t] < 0: returnFalse returnTrue
1 2 3 4 5 6 7 8 9 10 11
classSolution: defcanConstruct(self, ransomNote: str, magazine: str) -> bool: m = defaultdict(int) for i in magazine: m[i] += 1 for i in ransomNote: if i in m and m[i]: m[i] -= 1 else: returnFalse returnTrue
Go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//哈希表 funccanConstruct(ransomNote string, magazine string)bool { m := make(map[rune]int) for _, v := range magazine { m[v]++ } for _, v := range ransomNote { if value, ok := m[v]; ok && value > 0 { m[v]-- } else { returnfalse } } returntrue }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//数组 funccanConstruct(ransomNote, magazine string)bool { iflen(ransomNote) > len(magazine) { returnfalse } cnt := [26]int{} for _, ch := range magazine { cnt[ch-'a']++ } for _, ch := range ransomNote { cnt[ch-'a']-- if cnt[ch-'a'] < 0 { returnfalse } } returntrue }
#双指针法 classSolution: defthreeSum(self, nums: List[int]) -> List[List[int]]: nums.sort() # 先将数组排序 result = [] # 结果集 l = len(nums) for i inrange(l - 2): # 遍历数组,为什么是到 l - 2,因为我们需要找的是三个数的组合 if nums[i] > 0: # 如果第一个元素已经大于0,不需要进一步检查 break if i > 0and nums[i] == nums[i - 1]: # 如果当前数字和前一个相同,跳过这个数字,防止结果中出现重复的组合 continue left, right = i + 1, l - 1# 定义双指针 while left < right: # 当左指针小于右指针的时候,执行以下操作 total = nums[i] + nums[left] + nums[right] # 计算三个数的和 if total < 0: # 和小于0,需要增大,所以左指针右移 left += 1 elif total > 0: # 和大于0,需要减小,所以右指针左移 right -= 1 else: # 和为0,记录这个组合 result.append([nums[i], nums[left], nums[right]]) left += 1# 为了寻找下一个可能的组合,左指针右移 right -= 1# 右指针左移 while left < right and nums[left] == nums[left - 1]: # 跳过重复的组合 left += 1 while left < right and nums[right] == nums[right + 1]: # 跳过重复的组合 right -= 1 return result # 返回结果集
//双指针 functhreeSum(nums []int) [][]int { var result [][]int sort.Ints(nums) l := len(nums) for i := 0; i < l-2; i++ { if nums[i] > 0 { break } if i > 0 && nums[i] == nums[i-1] { continue } left, right := i+1, l-1 for left < right { sum := nums[i] + nums[left] + nums[right] if sum < 0 { left++ } elseif sum > 0 { right-- } else { result = append(result, []int{nums[i], nums[left], nums[right]}) left++ right-- for left < right && nums[left] == nums[left-1] { left++ } for left < right && nums[right] == nums[right+1] { right-- } } } } return result }
#双指针法 classSolution: deffourSum(self, nums: List[int], target: int) -> List[List[int]]: result = [] nums.sort() l = len(nums) for i inrange(l - 3): if i > 0and nums[i] == nums[i - 1]: continue for j inrange(l - 1, 2, -1): if j < l - 1and nums[j] == nums[j + 1]: continue left, right = i + 1, j - 1 while left < right: total = nums[i] + nums[j] + nums[left] + nums[right] if total < target: left += 1 elif total > target: right -= 1 else: result.append([nums[i], nums[j], nums[left], nums[right]]) left += 1 right -= 1 while left < right and nums[left] == nums[left - 1]: left += 1 while left < right and nums[right] == nums[right + 1]: right -= 1 return result
//双指针法,可类比三数之和这道题 funcfourSum(nums []int, target int) [][]int { var result [][]int sort.Ints(nums) l := len(nums) for i := 0; i < l-3; i++ { if i > 0 && nums[i] == nums[i-1] { continue } for j := l - 1; j > 2; j-- { if j < l-1 && nums[j] == nums[j+1] { continue } for left, right := i+1, j-1; left < right; { sum := nums[i] + nums[j] + nums[left] + nums[right] if sum < target { left++ } elseif sum > target { right-- } else { result = append(result, []int{nums[i], nums[j], nums[left], nums[right]}) left++ right-- for left < right && nums[left] == nums[left-1] { left++ } for left < right && nums[right] == nums[right+1] { right-- } } } } } return result }
//硬用哈希表,不建议 funcfourSum(nums []int, target int) [][]int { freq := make(map[int]int) for _, num := range nums { freq[num] = freq[num] + 1 } var ans [][]int for i := 0; i < len(nums); i++ { for j := i + 1; j < len(nums); j++ { for k := j + 1; k < len(nums); k++ { val := target - (nums[i] + nums[j] + nums[k]) if _, ok := freq[val]; ok { count := 0 if nums[i] == val { count++ } if nums[j] == val { count++ } if nums[k] == val { count++ } if freq[val] > count { quadruplet := []int{nums[i], nums[j], nums[k], val} sort.Ints(quadruplet) if !contains(ans, quadruplet) { ans = append(ans, quadruplet) } } } } } } return ans }
funccontains(quadruplets [][]int, quadruplet []int)bool { for _, q := range quadruplets { if equal(q, quadruplet) { returntrue } } returnfalse }
funcequal(a, b []int)bool { iflen(a) != len(b) { returnfalse } for i, v := range a { if v != b[i] { returnfalse } } returntrue }