面试笔试杂项积累-leetcode 216-220
2016-02-11 23:21
399 查看
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函数在加重复值时返回false192ms,和哈希表消耗相同时间。同样比排序慢
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 between
i 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] and
nums[j] is at most t and the difference between i and
j 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 be
num / t.
Another complication is that negative ints are allowed. A simple
num / 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;
}
}
相关文章推荐
- 面试笔试杂项积累-leetcode 211-215
- 一个程序员的顿悟:理想的程序员只比你多了6个一点点
- 初当技术面试官感悟:给面试者的忠告
- 开发web面试
- 岁月划过生命线(从阿里到微店)
- 第一篇日志,准备做程序员
- 数组指针面试题
- 为什么女程序员会这么少?
- 程序员应该每天写代码
- 程序员狂想曲
- #春节复习系列#操作系统相关知识
- 如果你恨一个程序员,忽悠他去做iOS开发
- 如果你恨一个程序员,忽悠他去做iOS开发
- Block的详细使用和面试注意点
- 一位程序员工作10年总结的13个忠告,却让很多人惋惜
- 【程序员在法国】一、辞别家乡千万里,组团空降法兰西
- 【程序员在法国】一、辞别家乡千万里,组团空降法兰西
- Android面试之View绘制流程以及invalidate()等相关方法分析
- 侃侃面试那些事儿:面试知识点梳理
- 那些年美帝码农找工作不能忘记的知识点