LeetCode Weekly Contest 34解题思路
2017-05-30 22:23
399 查看
LeetCode Weekly Contest 34解题思路
详细代码可以fork下Github上leetcode项目,不定期更新。赛题
本次周赛主要分为以下4道题:Leetcode 598. Range Addition II (5分)
Leetcode 599. Minimum Index Sum of Two Lists (6分)
Leetcode 565. Array Nesting (7分)
Leetcode 600. Non-negative Integers without Consecutive Ones (9分)
Leetcode 598. Range Addition II (5分)
Problem:Given an m * n matrix M initialized with all 0’s and several update operations.
Operations are represented by a 2D array, and each operation is represented by an array with two positive integers a and b, which means M[i][j] should be added by one for all 0 <= i < a and 0 <= j < b.
You need to count and return the number of maximum integers in the matrix after performing all the operations.
Example:
Input:
m = 3, n = 3
operations = [[2,2],[3,3]]
Output: 4
Explanation:
Initially, M =
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
After performing [2,2], M =
[[1, 1, 0],
[1, 1, 0],
[0, 0, 0]]
After performing [3,3], M =
[[2, 2, 1],
[2, 2, 1],
[1, 1, 1]]
So the maximum integer in M is 2, and there are four of it in M. So return 4.
Note:
The range of m and n is [1,40000].
The range of a is [1,m], and the range of b is [1,n].
The range of operations size won’t exceed 10,000.
只说关键点,每次更新都是从(0,0)到(a,b),所以只需要分别更新a,b为所有操作的最小值即可。
代码如下:
public int maxCount(int m, int n, int[][] ops) { int x = m; int y = n; for (int[] op : ops){ x = Math.min(x, op[0]); y = Math.min(y, op[1]); } return x * y; }
初始化为m和n,表明没有任何操作更新时,直接返回整个数组个数。
Leetcode 599. Minimum Index Sum of Two Lists (6分)
Problem:Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings.
You need to help them find out their common interest with the least list index sum. If there is a choice tie between answers, output all of them with no order requirement. You could assume there always exists an answer.
Example 1:
Input:
[“Shogun”, “Tapioca Express”, “Burger King”, “KFC”]
[“Piatti”, “The Grill at Torrey Pines”, “Hungry Hunter Steakhouse”, “Shogun”]
Output: [“Shogun”]
Explanation: The only restaurant they both like is “Shogun”.
Example 2:
Input:
[“Shogun”, “Tapioca Express”, “Burger King”, “KFC”]
[“KFC”, “Shogun”, “Burger King”]
Output: [“Shogun”]
Explanation: The restaurant they both like and have the least index sum is “Shogun” with index sum 1 (0+1).
Note:
The length of both lists will be in the range of [1, 1000].
The length of strings in both lists will be in the range of [1, 30].
The index is starting from 0 to the list length minus 1.
No duplicates in both lists.
意思是说找共同喜欢的饭店,且index之和最小。一道map题,把list1中的key和下标记录到map中,接着如果在list2中存在同样的key,便更新下标和,同时记录最小sum,但最小sum的记录存在信息缺失。(index1 + index2 < list1.length,在扫描key时,可能会把list1中的key记录进来,而此key是不在list2中的),所以我的做法是把list1的长度加入进来,这样,index1 + index2 > list1.length, 排除这种情况。
代码如下:
public String[] findRestaurant(String[] list1, String[] list2) { Map<String,Integer> map = new HashMap<>(); for (int i = 0; i < list1.length; i++){ map.put(list1[i], i); } int add = list1.length; int min = 1 << 30; for (int i = 0; i < list2.length; i++){ if (map.containsKey(list2[i])){ int value = map.get(list2[i]); map.put(list2[i], value + add + i); min = Math.min(min, value + add + i); } } List<String> ans = new ArrayList<>(); for (String key : map.keySet()){ int value = map.get(key); if (value == min){ ans.add(key); } } return ans.toArray(new String[0]); }
Leetcode 565. Array Nesting (7分)
Problem:A zero-indexed array A consisting of N different integers is given. The array contains all integers in the range [0, N - 1].
Sets S[K] for 0 <= K < N are defined as follows:
S[K] = { A[K], A[A[K]], A[A[A[K]]], … }.
Sets S[K] are finite for each K and should NOT contain duplicates.
Write a function that given an array A consisting of N integers, return the size of the largest set S[K] for this array.
Example :
Input: A = [5,4,0,3,1,6,2]
Output: 4
Explanation:
A[0] = 5, A1 = 4, A2 = 0, A3 = 3, A4 = 1, A[5] = 6, A[6] = 2.
One of the longest S[K]:
S[0] = {A[0], A[5], A[6], A2} = {5, 6, 2, 0}
Note:
N is an integer within the range [1, 20,000].
The elements of A are all distinct.
Each element of array A is an integer within the range [0, N-1].
union find, 尝试了递归,发现stack over flow,所以改成了迭代,需要注意,在搜索路径上,已经搜过的结点可以标记为-1,下次不需要再遍历。遍历所有可能的环,更新最大即可。
代码如下:
public int arrayNesting(int[] nums) { int size = 0; for (int i = 0; i < nums.length; i++){ if (nums[i] == -1) continue; int next = nums[i]; int step = 1; while (next != i){ step++; int tmp = nums[next]; nums[next] = -1; next = tmp; } size = Math.max(size, step); } return size; }
Leetcode 600. Non-negative Integers without Consecutive Ones (9分)
Problem:Given a positive integer n, find the number of non-negative integers less than or equal to n, whose binary representations do NOT contain consecutive ones.
Example :
Input: 5
Output: 5
Explanation:
Here are the non-negative integers <= 5 with their corresponding binary representations:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule.
Note:
1 <= n <= 109
这道题较难,让我们求非连续1的所有可能的个数,当然关键问题在于要≤n的情况。
≤n困扰了我很久,但此问题其实可以归简为求:
给定指定位数n,求在给定位数下非连续1的个数。
例如:
n = 2; 00 01 10 11 ans = 3; n = 3; 000 001 010 011 100 101 110 111 ans = 5
其实是一道排列组合题,排列组合题多半可以用递归式写出来,也就是说它是一道DP题,如何构建?
从 n-1 -> n 如何append? 假设f 为n位情况下,非连续1的个数, 则: f = "0"f[n-1] + "1"f[n-1]; 分出一位,我们构建递归式,可以是0,也可以是1,所以有两种情况,但上述递归式有问题。 主要在于:"1"f[n-1],如果f[n-1]是非连续1的个数,而f[n-1]的解,并没有约束开头不能是"1",所以 "1"f[n-1] = "10"f[n-2] + "11"f[n-2]; 而"11"f[n-2]是非法的,所以: f = "0"f[n-1] + "10"f[n-2]; 得: f = f[n-1] + f[n-2]; 这样,我们可以求得任何位数的非连续1的个数。
但,该问题是让我们求≤n的非连续1的个数,小于等于很关键,它的性质该如何利用?
例如:
num = 18 二进制表示如下: 18 = 0b10010 num = 1 0 0 1 0 pos = 4 3 2 1 0 开始利用f ,构建解。 当pos = 4 时,我们知道该位为1,那么它就存在两种情况: 1 X X X X = num 0 X X X X < num = num 的暂且可以不考虑,而 < num 的这种情况,非连续1的个数为:f[4] 因为第一位是0,所以4位数的任何非连续1都是它的解。 接着看 = num 的情况,因为本来就是1,所以pos--; pos = 3; 该位为9,由于 < num 的性质,不可能出现这位为1的情况,所以直接pos--; pos = 2; 同上。 pos = 1; 1 0 0 1 X 1 0 0 0 X 同样存在两种情况,需要加上f[1]; 上述情况num中并不存在连续的1,但给定的num也可能存在连续的1,如: num = 12; 二进制表示如下: 12 = 0b1100; num = 1 1 0 0; pos = 3 2 1 0; pos = 3时,可0可1 1 X X X 0 X X X f[3] pos = 2时,可0可1? 不能为1,而只能为0!否则会出现连续1,所以只能是: 1 0 X X f[2] 直接跳出循环(因为f[2]已经包含了 1 0 X X的所有情况)。
代码如下:
public int findIntegers(int num) { int[] f = new int[32]; f[0] = 1; f[1] = 2; for (int i = 2; i <= 31; i++) { f[i] = f[i - 1] + f[i - 2]; } int pos = 31; while (pos >= 0 && ((num & (1 << pos)) == 0)) pos--; if (pos == -1) return 1; int res = 0; int pre = 0; for (int i = pos; i >= 0; i--) { if (((num >> i) & 0x01) == 1) { res += f[i]; if (pre == 1){ res --; break; } pre = 1; }else{ pre = 0; } } return res + 1; }
相关文章推荐
- LeetCode Weekly Contest 43解题思路
- (Trie)LeetCode Weekly Contest 42 Q4 648. Replace Words
- LeetCode Weekly Contest 42解题思路
- LeetCode Weekly Contest 25 之 507.Perfect Number
- LeetCode Weekly Contest 52 Repeated String Match(string)
- LeetCode Weekly Contest 13-HammingDistance【易】
- LeetCode Weekly Contest 9 第九周周赛
- (几何)LeetCode Weekly Contest 32 D-Erect the Fence
- LeetCode Weekly Contest 30
- 【LeetCode】LeetCode Weekly Contest 16B
- 73th LeetCode Weekly Contest Escape The Ghosts
- leetcode Weekly Contest 67 -- 763. Partition Labels
- LeetCode Weekly Contest 25
- LeetCode Weekly Contest 13-TotalHamming Distance【中】
- LeetCode Weekly Contest 23 之 541. Reverse String II
- LeetCode Weekly Contest 24 之 538.Convert BST to Greater Tree
- LeetCode Weekly Contest 44解题思路
- LeetCode Weekly Contest 8
- LeetCode 660 Remove 9 (LeetCode Weekly Contest 45)
- LeetCode Weekly Contest 31解题思路