算法笔记之Hashtable

hashtable 是 实现算法 时常用的一种 有效数据结构,它的 高效性 在于,在需要快速插入和查询时,无论有多少个item, 它的操作时间总是接近于O(1)。

原因在于 hashtable 是散列的,它的key-value 几乎总是 一一对应的,而key 通常被我们称之为 hashcode。

设计hashtable的 关键在与 hashcode的 function 设计,即 在k和v之间所存在的对应关系,使得 v = f(k) ,该 f 称为 hash 函数。

在实际应用中,如何将hashcode 设计为范围尽可能快速有效地指向我们需要解决的值 是hashtable有效与否的关键。而且, 当发生hash冲突时 如何处理 也要取决于我们需求。

所谓的hash冲突指的是,当 key 的集合很大时,key值不同的元素可能会映射到同一个地址上去,即 key1 != key2, 但 f(key1) = f(key2)。

本文主要涉及 在小算法中 hash函数的设计。

最近在LeetCode遇到几个算法题, 细细想来 hashtable 是个不错的解决方法。

1. 2 sum

给出一个列表,返回和是指定的数的两个元素的下标。

如 : 给出 nums = [2, 7, 11, 15],  target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,

return [0, 1].

如果想用hashtable解决这个问题, 我们将hash函数设计为  f(k) = nums.index(k)  ,k为nums中的元素, value 为 k 在nums 中的索引,这样就能有效地找到k的同时, 找到有效的value。

def twoSum(nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        hashtable = {}
        for i, num in enumerate(nums):
            if target - num in hashtable :
                return [hashtable[target-num], i]
                
            hashtable[num] = i
            
        return []
        

2. 4Sum II:

Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such thatA[i] + B[j] + C[k] + D[l] is zero.

To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.

Example:

Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]

Output:
2

Explanation:
The two tuples are:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

Solution :

def fourSumCount( A, B, C, D):
        """
        :type A: List[int]
        :type B: List[int]
        :type C: List[int]
        :type D: List[int]
        :rtype: int
        """
        hashtable = {}
        for a in A:
            for b in B :
                if a + b in hashtable :
                    hashtable[a+b] += 1
                else :
                    hashtable[a+b] = 1
        count = 0         
        for c in C :
            for d in D :
                if -(c + d ) in hashtable :
                    count += hashtable[-c-d]
        return count 

这题与上题原理类似,只要设计好hash函数,就能有效解决问题。

3. 4Sum :

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note: The solution set must not contain duplicate quadruplets.

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.

A solution set is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]
题目要求找到和为target的不重复的所有四元组,这题除了暴力穷举的O(n^3) ,还想尽可能做得更好,受到同学启发,用hashtable, 让key = nums[i]+nums[j], value = [i, j],这样只需在hashtable中找到两个key值之和为target的数即可了,需要注意的一点是,最后给出答案时应删掉重复的四元组。

Solution :

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        nums.sort()
        results = []
        hashtable = {}
        for i,x in enumerate(nums[:-1]):
            for j in xrange(i+1,len(nums)):
                y = nums[j]
                if x+y in hashtable:
                    hashtable[x+y].append([i, j])
                else :
                    hashtable[x+y] = [[i, j]]
        results = []
        for k in hashtable:
            if target - k in hashtable :
                idxs = [x+y for x in hashtable[k] for y in hashtable[target-k] if len(set(x+y))== 4]
                res = [ [nums[y] for y in x ] for x in idxs]
                for r in res :
                    r.sort()
                    if r not in results :
                        results.append(r)
                    
        
        return results
        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值