Leetcode: 220. Contains Duplicate III

Description

Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.

Example

Input: nums = [1,0,1,1], k = 1, t = 2
Output: true

分析

steps 1:
           将下标 1 ~ k 的按大于或小于下标为 0的数组分成 (如果有等于 nums[0] 的直接返回 True) higher  和 lower 2 组。同时在分组的时候,也判断是否可以直接 返回 True。
遍立 lower 和 higher,如果有满足条件的直接返回 True.
求 nums[1] 的时候, 如果 nums[0] > nums[1] 。num[1] 只需要在 lower 组里面寻找是否有满足条件的数。如果 nums[0] < nums[1] , 则只需要在 higher 里面寻找 (因为 lower, higher 里面是没有满足条件的,只需要判断 nums[1+k] 是否满足条件就可以了)

code

class Solution(object):
    def _do(self, nums, k, t):
        if 2 > len(nums):
                return False
        lower, higher, N = [], [], len(nums)
        prev = nums[0]
        for i in range(1, min(N, k+1)):
            if t >= abs(nums[i] - prev):
                return True
            if prev > nums[i]:
                lower.append((nums[i], i))
            else:
                higher.append((nums[i], i))
        higher = sorted(higher)
        lower = sorted(lower)
        tmp, tmp_i = float('inf'), 0
        for v in higher:
            if t >= abs(v[0] - tmp) and k >= abs(v[1]-tmp_i):
                return True
            tmp, tmp_i = v

        for v in lower:
            if t >= abs(v[0] - tmp) and k >= abs(v[1]-tmp_i):
                return True
            tmp, tmp_i = v

        for i in range(1, N):
            if nums[i] > prev:
                temp = higher
            else:
                temp = lower
            prev = nums[i]
            if N > i+k:
                bisect.insort(temp, (nums[i+k], i+k))
            p = bisect.bisect_left(temp, (prev, i))
            lower_temp, higher_temp = temp[:p], temp[p:]
            for li in range(len(lower_temp)-1, -1, -1):
                if abs(lower_temp[li][1] -i) > k or lower_temp[li][1] == i:
                    continue
                if t >= abs(lower_temp[li][0]-prev):
                    return True
                lower = lower_temp[:li+1]
                break


            for hi in range(0, len(higher_temp)):
                if abs(higher_temp[hi][1]-i) > k or higher_temp[hi][1] == i:
                    continue
                if t >= abs(higher_temp[hi][0] - prev):
                    return True
                higher = higher_temp[hi:]
                break

        return False

总结

性能很差,只战胜 7 % 的提交

原文地址:https://www.cnblogs.com/tmortred/p/13380719.html