(二)哈希表

继续把基础算法例题都刷一遍,加油!

哈希表理论部分我就不贴出来了,有需要的话点下面蓝色字链接。
—> 《代码随想录》

有效的字母异位词

给定两个字符串 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个下标遍历并进行去重(必须)和剪枝(可省略),
#后半部分双指针代码基本一致。

免责声明:本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除。
原文作者:作者 卡哥:链接: 代码随想录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值