继续把基础算法例题都刷一遍,加油!
哈希表理论部分我就不贴出来了,有需要的话点下面蓝色字链接。
—> 《代码随想录》。
有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
s = "anagram",
t = "nagaram"
输出: true
def main(s,t):
record_lst = [0 for i in range(26)]
for i in range(len(s)):
record_lst[ord(s[i])-97] += 1 #ASCII 'A':65 'a':97
for j in range(len(t)):
record_lst[ord(t[j])-97] -= 1
print(record_lst)
for i in record_lst:
if i != 0:
return False
return True
s = "anagram"
t = "nagaram"
result = main(s,t)
print(result)
#s = "anagram", t = "nagaram",result = True
#s = "rat", t = "car",result = False
两个数组的交集
给定两个数组,编写一个函数来计算它们的交集。
输入:nums1 = [1,2,2,1],nums2 = [2,2],
输出:[2]
def main(nums1,nums2):
return list(set(nums1)&set(nums2))
nums1 = [1, 2, 2, 1]
nums2 = [2,2]
result = main(nums1,nums2)
print(result)
#nums1 = [1,2,2,1],nums2 = [2,2],result = [2]
#nums1 = [4,9,5],nums2 = [9,4,9,8,4]
快乐数
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
def calculate(num):
sum = 0
while num:
sum += (num % 10) ** 2
num //= 10
return sum
def main(num):
record_set = set()
while True:
num = calculate(num)
if num == 1:
return True
if num in record_set:
return False
else:
record_set.add(num)
num = 19
result = main(num)
print(result)
#num = 19,result=True
两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,
并返回他们的数组下标。
输入:nums = [2, 7, 11, 15]
输出:target = 9
def main(nums,target):
record = dict() #用于记录每个数字的下标
for idx,val in enumerate(nums):
if (target - val) in record:
return [record[target - val],idx]
else:
record[val] = idx
return None
nums = [2, 7, 11, 15]
target = 9
result = main(nums,target)
print(result)
#nums = [2, 7, 11, 15],result=[0,1]
四数相加II
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,
使得 A[i] + B[j] + C[k] + D[l] = 0。
解释:(0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
def main(A,B,C,D):
record_AB = dict()
count = 0
for a in A:
for b in B:
if (a + b) in record_AB:
record_AB[a+b] += 1
else:
record_AB[a+b] = 1
for c in C:
for d in D:
if -(c + d) in record_AB and record_AB[-(c+d)] >0:
record_AB[-(c+d)] -= 1
count += 1
return count
lst_A = [1,2]
lst_B = [-2.-1]
lst_C = [-1,2]
lst_D = [0,2]
result = main(lst_A,lst_B,lst_C,lst_D)
print(result)
#result = 2
赎金信
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom
能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
def main(A,B):
record = dict()
for i in B:
if i in record:
record[i] += 1
else:
record[i] = 1
for j in A:
val = record.get(j,None)
if val != None and val > 0:
record[j] -= 1
else:
return False
return True
str_A = 'ransom'
str_B = 'magazine'
result = main(str_A,str_B)
print(result)
#result = False
三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,
使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
输入:[-1, 0, 1, 2, -1, -4]
输出:[[-1, -1, 2], [-1, 0, 1]]
def main(lst):
record = []
lst.sort() #先进行排序利于后面去重
for i in range(len(lst)):
if lst[i] > 0: #剪枝,因为是升序,若i为正数,l和r肯定也是正
break
if i > 0 and lst[i] == lst[i-1]: #对i进行去重
continue
left,right = i+1,len(lst)-1 #双指针
while left < right:
sqt = lst[i] + lst[left] + lst[right]
if sqt > 0:
right -= 1
elif sqt < 0:
left += 1
else:
record.append([lst[i],lst[left],lst[right]])
#这里要注意left和right也要去重
while lst[left] == lst[left+1]:left += 1
while lst[right] == lst[right-1]:right -= 1
left += 1 #上面取sqt之后,就要l和r同时缩一位在判断
right -= 1
return record
lst = [-1, 0, 1, 2, -1, -4]
result = main(lst)
print(result)
#result = [[-1, -1, 2], [-1, 0, 1]]
四数之和
题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素
a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
输入:lst = [1, 0, -1, 0, -2, 2],target = 0
输出:[[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
def main(lst,target):
record = []
lst.sort()
n = len(lst)
for i in range(n):
if target > 0 and lst[i] > target: #剪枝
break
if i > 0 and lst[i] == lst[i-1]: #去重
continue
for j in range(i+1,n):
if target > 0 and lst[i] + lst[j] > target: #第二次剪枝
break
if j > i+1 and lst[j] == lst[j-1]:
continue #第二次去重。因此n数之和有n-2次的去重和剪枝。
left,right = j+1,n-1
while left < right: #后半部分同样是双指针,与三数之和一样
if lst[i] + lst[j] + lst[left] + lst[right] > target:
right -= 1
elif lst[i] + lst[j] + lst[left] + lst[right] < target:
left += 1
else:
record.append([lst[i], lst[j], lst[left], lst[right]])
left += 1
right -= 1
return record
lst = [1, 0, -1, 0, -2, 2]
target = 0
result = main(lst,target)
print(result)
#lst = [1, 0, -1, 0, -2, 2],target=0
#result = [[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]
#注意target为负的情况,负数相加会更小,因此要确保最左边的lst[i]>0且lst[i]>target才可break。
#所以无论是三数之和,四树之和,n(n》3)树之和。只要对前n-2个下标遍历并进行去重(必须)和剪枝(可省略),
#后半部分双指针代码基本一致。
免责声明:本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除。
原文作者:作者 卡哥:链接: 代码随想录