程式碼隨想錄演算法訓練營第七天
383贖金信
https://leetcode.cn/problems/ransom-note/submissions/537782865/
383贖金信程式碼隨想錄
https://programmercarl.com/0383.贖金信.html#思路
四數之和2
https://leetcode.cn/problems/4sum-ii/
四數之和2程式碼隨想錄
https://programmercarl.com/0454.四數相加II.html#演算法公開課
三數之和
https://leetcode.cn/problems/3sum/description/
三數之和程式碼隨想錄
https://programmercarl.com/0015.三數之和.html#思路
四數之和
https://leetcode.cn/problems/4sum/description/
四數之和程式碼隨想錄
https://programmercarl.com/0018.四數之和.html#演算法公開課
383贖金信
題目
給你兩個字串:ransomNote 和 magazine ,判斷 ransomNote 能不能由 magazine 裡面的字元構成。
如果可以,返回 true ;否則返回 false 。
magazine 中的每個字元只能在 ransomNote 中使用一次。
題解
和前面計數一樣
四數之和2
題目
給你四個整數陣列 nums1、nums2、nums3 和 nums4 ,陣列長度都是 n ,請你計算有多少個元組 (i, j, k, l) 能滿足:
- 0 <= i, j, k, l < n
- nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
題解
- 不要求題解中不出現重複數字
- 從不同陣列中挑數字 不需要考慮重複問題
- 更簡單
- 1個雜湊表 分別對2組陣列計算即可
題解程式碼
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
hash_table ={}
for num_1 in range(len(nums1)):
for num_2 in range(len(nums2)):
num = nums1[num_1]+nums2[num_2]
hash_table[num] = hash_table.get(num,0)+1
res = 0
for num_3 in range(len(nums3)):
for num_4 in range(len(nums4)):
num = 0-(nums3[num_3]+nums4[num_4])
if num in hash_table:
res = res + hash_table[num]
return res
三數之和 + 四數之和
三數之和題目
給你一個整數陣列 nums ,判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i != j、i != k 且 j != k ,同時還滿足 nums[i] + nums[j] + nums[k] == 0 。請
你返回所有和為 0 且不重複的三元組。
注意:答案中不可以包含重複的三元組。
四數之和題目
給你一個由 n 個整陣列成的陣列 nums ,和一個目標值 target 。請你找出並返回滿足下述全部條件且不重複的四元組 [nums[a], nums[b], nums[c], nums[d]] (若兩個四元組元素一一對應,則認為兩個四元組重複):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意順序 返回答案 。
題解(同類):
- 首先排序
- 固定指標,剩下由雙指標計算兩數之和;
- 一開始使用二分法 這裡不能用二分法 因為不確定一定存在;
- 注意剪枝
- 個數剪枝:不滿足個數 直接返回
- 遍歷函式剪枝(target不確定時,需要確定數字正負):超過target返回->因為是按大小排序的
- 指標剪枝:和前面相同直接跳過
題解程式碼
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
if len(nums)<4:
return []
##首先排除無結果的輸入
nums = sorted(nums)
res = []
##初始化
##第一個遍歷迴圈
n = len(nums)
for i in range(n):
if nums[i]>target and nums[i]>0:
return res
if i>0 and nums[i]==nums[i-1]:
continue
##第二個遍歷迴圈
for j in range(i+1,n):
if nums[i]+nums[j]>target and nums[j]>0:
break
if j>i+1 and nums[j]==nums[j-1]:
continue
l = j+1
r = n-1
##指標尋找target
while l<r:
if nums[i]+nums[j]+nums[l]+nums[r]<target:
l = l+1
elif nums[i]+nums[j]+nums[l]+nums[r]>target:
r = r-1
else:
res.append([nums[i],nums[j],nums[l],nums[r]])
while 0<l<n-1 and nums[l+1]==nums[l]:
l = l+1
while l<r<n and nums[r-1]==nums[r]:
r = r-1
##2個指標固定以後,可能有n個答案
l = l+1
r = r-1
return res