练习:leecode1.15.18

哈希表法,双指针夹逼法

def twoSum(nums, target):
    hashmap = {}
    ret = []
    l = len(nums)
    target = 0
    nums.sort()
    for i, a in enumerate(nums[:]):
        if i < l-1 and nums[i] == nums[i+1]:
            continue
        if hashmap.__contains__(target - a):
            ret.append([a, target - a])
        if a in hashmap:
            hashmap[a].append(i)
        else:
            hashmap[a] = [i]
    return ret



def threeSum(nums):
    if len(nums) < 3:                           # 特判
        return []
    nums.sort()
    ret = []
    l = len(nums)
    if nums[0] == 0 and nums[l-1] == 0:         # 特判
            return [[0, 0, 0]]
    for j in range(l-2):
        if nums[j] <= 0 :       # 特判
            if j > 0 and nums[j] == nums[j - 1]:
                continue  # 去重复
            L = j + 1
            R = l - 1
            while L < R:
                sum = nums[j] + nums[L] + nums[R]
                if sum == 0:
                    v = [nums[j], nums[L], nums[R]]
                    ret.append(v)
                    R -= 1
                    L += 1
                    while L < R and nums[R] == nums[R + 1]:
                        R -= 1
                    while L < R and nums[L] == nums[L - 1]:
                        L += 1
                elif sum > 0:
                    R -= 1
                    while L < R and nums[R] == nums[R + 1]:
                        R -= 1
                else:
                    L += 1
                    while L < R and nums[L] == nums[L - 1]:
                        L += 1
    return ret


def fourSum(nums, target):
    if len(nums) < 4:
        return []

    # 将数列进行排序并且每个数字只保存其中的4个
    sort_nums = sorted(nums)
    new_nums = [sort_nums[0]]
    count = 1  # 统计当前数字在new_nums中的个数
    for num in sort_nums[1:]:
        if num == new_nums[-1]:
            if count == 4:
                continue
            else:
                count += 1
                new_nums.append(num)
        else:
            count = 1
            new_nums.append(num)

    # 遍历new_nums并找出所有符合条件的结果
    sum_dict = {}  # 将数对的和作为键把数对保存在字典中
    result = set()
    min_sum = new_nums[0] + new_nums[1]
    max_sum = new_nums[-1] + new_nums[-2]
    n = len(new_nums)
    for i in range(n):
        for j in range(i + 1, n):
            cur_sum = new_nums[i] + new_nums[j]
            # 如果当前数对加上最小数对已经大于target,那么它及其后面的数对与任何数对的和都大于target,提前结束循环
            if cur_sum + min_sum > target:
                break
            # 如果当前数对加上最大数对仍小于target,那么它和任何数对的和一定都小于target,因此没必要保存它的和
            if cur_sum + max_sum < target:
                continue
            # 如果当前遍历过相同数对那么进行下一次遍历
            if new_nums[j] == new_nums[j - 1] and j > i + 1:
                continue

            # 判断是否存在已经保存过的数对的和与当前数对的和为target
            if target - cur_sum in sum_dict:
                for p in sum_dict[target - cur_sum]:
                    if i in p or j == p[1]:
                        continue
                    result.add(tuple(sorted([new_nums[p[0]], new_nums[p[1]], new_nums[i], new_nums[j]])))

            # 无论是否存在配对的数对都要把当前数对的结果存入字典以cur_sum为键的桶中
            else:
                if cur_sum in sum_dict:
                    sum_dict[cur_sum].append([i, j])
                else:
                    sum_dict[cur_sum] = [[i, j]]

    return [list(res) for res in result]
发布了15 篇原创文章 · 获赞 0 · 访问量 380

猜你喜欢

转载自blog.csdn.net/mynameisJW/article/details/104878865
今日推荐