1. 程式人生 > >220. Contains Duplicate III(python+cpp)

220. Contains Duplicate III(python+cpp)

題目:

Given an array of integers, find out whether there are two distinct indices i and jin 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 1:

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

Example 2:

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

Example 3:

Input: nums = [1,5,9,1,5,9], k = 2, t = 3 
Output: false

解釋: 感覺還是用字典做,在II的基礎上改的程式碼,超時了。(如果t的範圍特別大就窒息)。 然後有一個用python的OrderDict的解法,解釋如下: python OrderedDict() 如果:| nums[i] - nums[j] | <= t 式a 等價:| nums[i] / t - nums[j] / t | <= 1 式b 推出:| floor(nums[i] / t) - floor(nums[j] / t) | <= 1

式c 等價: floor(nums[j] / t) ∈ {floor(nums[i] / t) - 1, floor(nums[i] / t), floor(nums[i] / t) + 1}式d 其中式b是式c的充分非必要條件,因為逆否命題與原命題等價,所以: 如果: floor(nums[j] / t) ∉ {floor(nums[i] / t) - 1, floor(nums[i] / t), floor(nums[i] / t) + 1}非d 推出:| nums[i] - nums[j] | > t 非a 如果 popitem(last=False) 將彈出第一個插入的鍵值對 python程式碼:

from collections import OrderedDict
class Solution(object):
    def containsNearbyAlmostDuplicate(self, nums, k, t):
        """
        :type nums: List[int]
        :type k: int
        :type t: int
        :rtype: bool
        """
        if k<1 or t<0:
            return False
        _dict=OrderedDict()
        for num in nums:
            key=num if not t else num//t
            for m in (_dict.get(key-1),_dict.get(key),_dict.get(key+1)):
                if m is not None and abs(num-m)<=t:
                    return True
            if len(_dict)==k:
                _dict.popitem(False)
            _dict[key]=num
        return False

覺得上面的解法不僅難以理解而且速度還慢,看了這道題的標籤居然是BST?然後看了下Disscuss,感覺智商在被踩在地上摩擦。 python程式碼:

class Solution(object):
    def containsNearbyAlmostDuplicate(self, nums, k, t):
        """
        :type nums: List[int]
        :type k: int
        :type t: int
        :rtype: bool
        """
        n=len(nums)
        if t==0 and n==len(set(nums)):
            return False
        for i in range(n):
            for j in range(1,k+1):
                if i+j>=n:
                    break
                if abs(nums[i+j]-nums[i])<=t:
                    return True
        return False

一樣的程式碼,c++超時了,而且需要考慮一下c++的數值範圍的問題(超時是因為剛開始沒有set一下以後在判斷,加上了居然就ac了,神奇,看來考慮一些頁數情況真的有利於節省執行時間) c++程式碼:

#incclude <cmath>
using namespace std;
class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        
        int n=nums.size();
        vector< long >new_nums(nums.begin(),nums.end());
        set<int> _set(nums.begin(),nums.end());
        if(t==0 && n==_set.size())
            return false;
        for(int i=0;i<n;i++)
        {
            for(int j=1;j<=k;j++)
            {
                if(i+j>=n)
                    break;
                if(labs(new_nums[i+j]-new_nums[i])<=t)
                {
                    return true;
                }
                    
            }
        }
        return false;
    }
};

總結: