1. 程式人生 > 實用技巧 >Leetcode: 220. Contains Duplicate III

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 % 的提交