面试笔试杂项积累-leetcode 216-220

来源:互联网 发布:局域网演示软件 编辑:程序博客网 时间:2024/06/15 23:09

216.216-Combination Sum III-Difficulty: Medium

Find all possible combinations of k numbers that add up to a numbern, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.

Ensure that numbers within the set are sorted in ascending order.


Example 1:

Input: k = 3, n = 7

Output:

[[1,2,4]]

Example 2:

Input: k = 3, n = 9

Output:

[[1,2,6], [1,3,5], [2,3,4]]

思路

找到所有k个数的和是n的数组集合

回溯

public class Solution {  IList<IList<int>> fin = new List<IList<int>>();    public IList<IList<int>> CombinationSum3(int k, int n)    {        recursion(new List<int>(), 1, 0, k, n);        return fin;    }    void recursion(List<int> temp, int start, int sum, int k, int n)//1-9    {        for (int i = start; i <10; i++)        {            if (sum + i == n)            {                if (temp.Count + 1 == k)                {                    temp.Add(i);                    fin.Add(new List<int>(temp));                    temp.RemoveAt(temp.Count - 1);                    return;                }                return;            }            else if (sum + i > n)                return;            if (temp.Count + 1 > k)                return;            temp.Add(i);            recursion(temp, i + 1, sum + i, k, n);            temp.RemoveAt(temp.Count - 1);        }    }}

217.217-Contains Duplicate-Difficulty: Easy

Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.

方法一

思路

查看数组是否含有重复数字

先排序,后遍历比较-176ms

    public bool ContainsDuplicate(int[] nums)//通过1//176 ms     {        Array.Sort(nums);        for (int i = 1; i < nums.Length; i++)            if (nums[i-1] == nums[i])                return true;        return false;    }

方法二

思路

使用一个数据结构,哈希表,不能使用list,list是超时的,因为哈希的key是直接映射地址的,查询获取操作消耗很少,而list的contains应该是遍历查询的,消耗很大。

这里是使用哈希表这个数据结构-192ms

不知道为什么使用哈希反而比排序的慢了

    public bool ContainsDuplicate(int[] nums)//通过2//192ms    {        Hashtable hash = new Hashtable();        for (int i = 0; i < nums.Length; i++)            if (hash.ContainsKey(nums[i]))                return true;            else                hash.Add(nums[i],1);        return false;    }

方法三

思路

巧妙利用hashset的add,add函数在加重复值时返回false

192ms,和哈希表消耗相同时间。同样比排序慢

    public bool ContainsDuplicate(int[] nums)//通过3//192ms    {        HashSet<int> hash = new HashSet<int>();        for (int i = 0; i < nums.Length; i++)            if (!hash.Add(nums[i]))                return true;        return false;    }

219.219-Contains Duplicate II-Difficulty: Easy

Given an array of integers and an integer k, find out whether there are two distinct indicesi and j in the array such that nums[i] = nums[j] and the difference betweeni and j is at most k.

方法一

思路

存在i和j相差k以内,并且nums[i] = nums[j]

返回true,不存在返回false

遍历判断,时间复杂度O(k*n)

public class Solution {    public bool ContainsNearbyDuplicate(int[] nums, int k) {                for (int i = 0; i < nums.Length - 1; i++)            for (int j = i + 1; j < i + k+1 && j < nums.Length ; j++)            {                if (nums[i] == nums[j])                    return true;            }        return false;    }}

方法二

思路

和217题方法三一样,使用hashset的Add判断重复,时间复杂度O(n)

public boolean containsNearbyDuplicate(int[] nums, int k) {    HashSet<Integer> hs=new HashSet<>();    for(int i=0;i<nums.length;i++)    {        if(hs.add(nums[i])==false) return true;        if(hs.size()==k+1) hs.remove(nums[i-k]);    }    return false;}

220.220-Contains Duplicate III-Difficulty: Medium

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

思路

与219相近

存在i和j相差k以内,并且nums[i] 与nums[j]相差不超过t

返回true,不存在返回false

相差不超过t可以用绝对值来判断,也就是Math.Abs。

这里不能用单纯的遍历来判断了,会超时

使用桶排序

参考:

https://leetcode.com/discuss/38206/ac-o-n-solution-in-java-using-buckets-with-explanation


As a followup question, it naturally also requires maintaining a window of size k. When t == 0, it reduces to the previous question so we just reuse the solution.

Since there is now a constraint on the range of the values of the elements to be considered duplicates, it reminds us of doing a range check which is implemented in tree data structure and would take O(LogN) if a balanced tree structure is used, or doing a bucket check which is constant time. We shall just discuss the idea using bucket here.

Bucketing means we map a range of values to the a bucket. For example, if the bucket size is 3, we consider 0, 1, 2 all map to the same bucket. However, if t == 3, (0, 3) is a considered duplicates but does not map to the same bucket. This is fine since we are checking the buckets immediately before and after as well. So, as a rule of thumb, just make sure the size of the bucket is reasonable such that elements having the same bucket is immediately considered duplicates or duplicates must lie within adjacent buckets. So this actually gives us a range of possible bucket size, i.e. t and t + 1. We just choose it to be t and a bucket mapping to benum / t.

Another complication is that negative ints are allowed. A simplenum / t just shrinks everything towards 0. Therefore, we can just reposition every element to start from Integer.MIN_VALUE.

Edits:

Actually, we can use t + 1 as the bucket size to get rid of the case when t == 0. It simplifies the code. The above code is therefore the updated version.


public class Solution {    public bool ContainsNearbyAlmostDuplicate(int[] nums, int k, int t) {                 if (k < 1 || t < 0) return false;        Hashtable map = new Hashtable();        for (int i = 0; i < nums.Length; i++)        {            long remappedNum = (long)nums[i] - int.MinValue;            long bucket = remappedNum / ((long)t + 1);            if (map.ContainsKey(bucket)                    || (map.ContainsKey(bucket - 1) && remappedNum - (long)map[bucket - 1] <= t)                        || (map.ContainsKey(bucket + 1) && (long)map[bucket + 1] - remappedNum <= t))                return true;            if (map.Count >= k)//map..EntrySet().size()            {                long lastBucket = ((long)nums[i - k] - int.MinValue) / ((long)t + 1);                map.Remove(lastBucket);            }            map.Add(bucket, remappedNum);        }        return false;    }}










0 0
原创粉丝点击