LeetCode Weekly Contest 47
2017-08-27 16:16
330 查看
自己还是太弱了quq,所以觉得看别人的代码来提高姿势水平比花很多时间想要有意义吧orz
每道题的解答都摘自Discuss,选的都是up vote最多的:
665. Non-decreasing Array
Given an array with
by modifying at most
We define an array is non-decreasing if
<= i < n).
Example 1:
[/code]
Example 2:
Note: The
解答:
Java的:
另解:
"NON-DECREASING" is a double negative. This is the same as an array sorted in ascending order where
Find the first exception to this rule where
then see if the rest of the array is sorted in ascending order (
666. Path Sum IV
If the depth of a tree is smaller than
of three-digits integers.
For each integer in this list:
The hundreds digit represents the depth
The tens digit represents the position
to,
The units digit represents the value
Given a list of
than 5. You need to return the sum of all paths from the root towards the leaves.
Example 1:
Example 2:
解答:
How do we solve problem like this if we were given a normal tree? Yes, traverse it, keep a root to leaf running sum. If we see a leaf node (node.left == null && node.right == null), we add the running sum to the final result.
Now each tree node is represented by a number. 1st digits is the
that
of
get the sum.
The idea is, we can form a
first two digits which marks the position of a node in the tree. The
that node. Thus, we can easily find a node's left and right children using math.
Formula: For node
right child is
Given above HashMap and formula, we can traverse the
另一个解答(没有用HashMap):
Regardless whether these nodes exist:
the position of left child is always
the position of right child is always
the position of parent is always
Solution C++ Array
Solution C++ map
If we use map, we don't need to do the boundary check at little extra cost of memory.
Solution C++ - queue
Solution Java
667. Beautiful Arrangement II
Given two integers
you need to construct a list which contains
obeys the following requirement:
Suppose this list is [a1, a2, a3,
... , an], then the list [|a1 -
a2|, |a2 - a3|,
|a3 - a4|, ... , |an-1 -
an|] has exactly
integers.
If there are multiple answers, print any of them.
Example 1:
Example 2:
解答:
if you have
be
if
8.
This can be done by picking numbers interleavingly from head and tail,
This is a case where
When k is less than that, simply lay out the rest
order(all diff is 1). Say if k is 5:
C++
C++ Compact
Java
另解:
The requirement of k distinct distance can be achieved from 1, 2, ..., k+1 (<= n), by the following strategy:
Then append the remaining numbers to the list.
Nearly every one have used the Multiplication Table. But could you find out the
number quickly from the multiplication table?
Given the height
a
you need to return the
Example 1:
Example 2:
Note:
The
be in the range [1, 30000].
The
解答:
Binary Search:
然后有人说这道题抄了codeforces:
This exact problem is found on the Codeforces OJ on this link:
http://codeforces.com/contest/448/problem/D
Its solution is also fully written on stack overflow on this link:
https://stackoverflow.com/questions/33464901/using-binary-search-to-find-k-th-largest-number-in-nm-multiplication-table
I found several people who blindly copied that code and got AC!. The reason I know this problem was on Stackoverflow was because Iwas the one who asked that question in 2015!!
每道题的解答都摘自Discuss,选的都是up vote最多的:
665. Non-decreasing Array
Given an array with
nintegers, your task is to check if it could become non-decreasing
by modifying at most
1element.
We define an array is non-decreasing if
array[i] <= array[i + 1]holds for every
i(1
<= i < n).
Example 1:
Input: [4,2,3] Output: True Explanation: You could modify the first [code]4to
1to get a non-decreasing array.
[/code]
Example 2:
Input: [4,2,1] Output: False Explanation: You can't get a non-decreasing array by modify at most one element.
Note: The
nbelongs to [1, 10,000].
解答:
Java的:
class Solution { public boolean checkPossibility(int[] nums) { int n = nums.length, count = 0; for (int i = 0; i + 1 < n; i++) { if (nums[i] > nums[i + 1]) { count++; if (i > 0 && nums[i + 1] < nums[i - 1]) nums[i + 1] = nums[i]; else nums[i] = nums[i + 1]; } } return count <= 1; } }
另解:
"NON-DECREASING" is a double negative. This is the same as an array sorted in ascending order where
nums[i] <= nums[i+1].
Find the first exception to this rule where
nums[i] > nums[i+1],
then see if the rest of the array is sorted in ascending order (
without nums[i 4000 ]) XOR (
without nums[i+1]).
class Solution { public: bool checkPossibility(vector<int>& nums) { for (int i=0; i < nums.size()-1; i++){ if (nums[i] > nums[i+1]){ int temp = nums[i]; // // "erase" nums[i], then check if nums is sorted without nums[i] // nums[i] = nums[i+1]; if (is_sorted(nums.begin(), nums.end())) { return true; } // // "erase" nums[i+1], then check if nums is sorted without nums[i+1] // nums[i+1] = nums[i] = temp; if (is_sorted(nums.begin(), nums.end())) { return true; } // // nums is NOT sorted (without nums[i] XOR without nums[i+1]) // return false; } } return true; } };
666. Path Sum IV
If the depth of a tree is smaller than
5, then this tree can be represented by a list
of three-digits integers.
For each integer in this list:
The hundreds digit represents the depth
Dof this node,
1 <= D <= 4.
The tens digit represents the position
Pof this node in the level it belongs
to,
1 <= P <= 8. The position is the same as that in a full binary tree.
The units digit represents the value
Vof this node,
0 <= V <= 9.
Given a list of
ascendingthree-digits integers representing a binary with the depth smaller
than 5. You need to return the sum of all paths from the root towards the leaves.
Example 1:
Input: [113, 215, 221] Output: 12 Explanation: The tree that the list represents is: 3 / \ 5 1 The path sum is (3 + 5) + (3 + 1) = 12.
Example 2:
Input: [113, 221] Output: 4 Explanation: The tree that the list represents is: 3 \ 1 The path sum is (3 + 1) = 4.
解答:
How do we solve problem like this if we were given a normal tree? Yes, traverse it, keep a root to leaf running sum. If we see a leaf node (node.left == null && node.right == null), we add the running sum to the final result.
Now each tree node is represented by a number. 1st digits is the
level, 2nd is the
positionin
that
level(note that it starts from
1instead
of
0). 3rd digit is the value. We need to find a way to traverse this
treeand
get the sum.
The idea is, we can form a
treeusing a HashMap. The
keyis
first two digits which marks the position of a node in the tree. The
valueis value of
that node. Thus, we can easily find a node's left and right children using math.
Formula: For node
xy?its left child is
(x+1)(y*2-1)?and
right child is
(x+1)(y*2)?
Given above HashMap and formula, we can traverse the
tree. Problem is solved!
class Solution { int sum = 0; Map<Integer, Integer> tree = new HashMap<>(); public int pathSum(int[] nums) { if (nums == null || nums.length == 0) return 0; for (int num : nums) { int key = num / 10; int value = num % 10; tree.put(key, value); } traverse(nums[0] / 10, 0); return sum; } private void traverse(int root, int preSum) { int level = root / 10; int pos = root % 10; int left = (level + 1) * 10 + pos * 2 - 1; int right = (level + 1) * 10 + pos * 2; int curSum = preSum + tree.get(root); if (!tree.containsKey(left) && !tree.containsKey(right)) { sum += curSum; return; } if (tree.containsKey(left)) traverse(left, curSum); if (tree.containsKey(right)) traverse(right, curSum); } }
另一个解答(没有用HashMap):
0 0 1 0 1 2 3 0 1 2 3 4 5 6 7
Regardless whether these nodes exist:
the position of left child is always
parent_pos * 2;
the position of right child is always
parent_pos * 2 + 1;
the position of parent is always
child_pos / 2;
Solution C++ Array
class Solution { public: int pathSum(vector<int>& nums) { int m[5][8] = {}; for (int n : nums) { int i = n / 100; // i is 1 based index; int j = (n % 100) / 10 - 1; // j used 0 based index; int v = n % 10; m[i][j] = m[i - 1][j / 2] + v; } int sum = 0; for (int i = 1; i < 5; i++) { for (int j = 0; j < 8; j++) { if (i == 4 || m[i][j] && !m[i + 1][j * 2] && !m[i + 1][j * 2 + 1]){ sum += m[i][j]; } } } return sum; } };
Solution C++ map
If we use map, we don't need to do the boundary check at little extra cost of memory.
class Solution { public: int pathSum(vector<int>& nums) { map<int, map<int, int>> m; for (int n : nums) { int i = n / 100 - 1; // i is 0 based index; int j = (n % 100) / 10 - 1; // j used 0 based index; int v = n % 10; m[i][j] = m[i - 1][j / 2] + v; } int sum = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { sum += m[i][j] && !m[i + 1][j * 2] && !m[i + 1][j * 2 + 1] ? m[i][j] : 0; } } return sum; } };
Solution C++ - queue
class Solution { public: int pathSum(vector<int>& nums) { if (nums.empty()) return 0; int sum = 0; queue<info> q; info dummy(0); info* p = &dummy; // parent start with dummy info, root have no real parent; for (int n : nums) { info c(n); // child; while (!p->isparent(c) && !q.empty()) { sum += p->leaf ? p->v : 0; p = &q.front(); q.pop(); } p->leaf = false; c.v += p->v; q.push(c); } while (!q.empty()) { sum += q.front().v; q.pop(); } return sum; } private: struct info { int i, j, v; bool leaf; info(int n) : i(n / 100 - 1), j((n % 100) / 10 - 1), v(n % 10), leaf(true) {}; bool isparent(info other) { return i == other.i - 1 && j == other.j / 2;}; }; };
Solution Java
class Solution { public int pathSum(int[] nums) { int[][] m = new int[5][8]; for (int n : nums) { int i = n / 100; // i is 1 based index; int j = (n % 100) / 10 - 1; // j used 0 based index; int v = n % 10; m[i][j] = m[i - 1][j / 2] + v; } int sum = 0; for (int i = 1; i < 5; i++) { for (int j = 0; j < 8; j++) { if (i == 4 || m[i][j] != 0 && m[i + 1][j * 2] == 0 && m[i + 1][j * 2 + 1] == 0){ sum += m[i][j]; } } } return sum; } }
667. Beautiful Arrangement II
Given two integers
nand
k,
you need to construct a list which contains
ndifferent positive integers ranging from
1to
nand
obeys the following requirement:
Suppose this list is [a1, a2, a3,
... , an], then the list [|a1 -
a2|, |a2 - a3|,
|a3 - a4|, ... , |an-1 -
an|] has exactly
kdistinct
integers.
If there are multiple answers, print any of them.
Example 1:
Input: n = 3, k = 1 Output: [1, 2, 3] Explanation: The [1, 2, 3] has three different positive integers ranging from 1 to 3, and the [1, 1] has exactly 1 distinct integer: 1.
Example 2:
Input: n = 3, k = 2 Output: [1, 3, 2] Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.
解答:
if you have
nnumber, the maximum
kcan
be
n - 1;
if
nis 9, max
kis
8.
This can be done by picking numbers interleavingly from head and tail,
// start from i = 1, j = n; // i++, j--, i++, j--, i++, j-- 1 2 3 4 5 9 8 7 6 out: 1 9 2 8 3 7 6 4 5 dif: 8 7 6 5 4 3 2 1
This is a case where
kis exactly
n - 1
When k is less than that, simply lay out the rest
(i, j)in incremental
order(all diff is 1). Say if k is 5:
i++, j--, i++, j--, i++, i++, i++ ... 1 9 2 8 3 4 5 6 7 8 7 6 5 1 1 1 1
C++
class Solution { public: vector<int> constructArray(int n, int k) { vector<int> res; for (int i = 1, j = n; i <= j; ) { if (k > 1) { res.push_back(k-- % 2 ? i++ : j--); } else { res.push_back(k % 2 ? i++ : j--); } } return res; } };
C++ Compact
class Solution { public: vector<int> constructArray(int n, int k) { vector<int> res; for (int i = 1, j = n; i <= j; ) res.push_back(k > 1 ? (k-- % 2 ? i++ : j--) : (k % 2 ? i++ : j--)); return res; } };
Java
class Solution { public int[] constructArray(int n, int k) { int[] res = new int ; for (int i = 0, l = 1, r = n; l <= r; i++) res[i] = k > 1 ? (k-- % 2 != 0 ? l++ : r--) : (k % 2 != 0? l++ : r--); return res; } }
另解:
The requirement of k distinct distance can be achieved from 1, 2, ..., k+1 (<= n), by the following strategy:
1, k+1, 2, k, 3, k-1 ...; The distance of this sequence is k, k-1, k-2, ..., 2, 1
Then append the remaining numbers to the list.
class Solution { public: vector<int> constructArray(int n, int k) { int l = 1, r = k+1; vector<int> ans; while (l <= r) { ans.push_back(l++); if (l <= r) ans.push_back(r--); } for (int i = k+2; i <= n; i++) ans.push_back(i); return ans; } };
668. Kth largest Number in Multiplication Table
Nearly every one have used the Multiplication Table. But could you find out the k-thlargest
number quickly from the multiplication table?
Given the height
mand the length
nof
a
m * nMultiplication Table, and a positive integer
k,
you need to return the
k-thlargest number in this table.
Example 1:
Input: m = 3, n = 3, k = 5 Output: Explanation: The Multiplication Table: 1 2 3 2 4 6 3 6 9 The 5-th largest number is 3 (1, 2, 2, 3, 3).
Example 2:
Input: m = 2, n = 3, k = 6 Output: Explanation: The Multiplication Table: 1 2 3 2 4 6 The 6-th largest number is 6 (1, 2, 2, 3, 4, 6).
Note:
The
mand
nwill
be in the range [1, 30000].
The
kwill be in the range [1, m * n]
解答:
Binary Search:
class Solution { public int findKthNumber(int m, int n, int k) { int low = 1 , high = m * n + 1; while (low < high) { int mid = low + (high - low) / 2; int c = count(mid, m, n); if (c >= k) high = mid; else low = mid + 1; } return high; } private int count(int v, int m, int n) { int count = 0; for (int i = 1; i <= m; i++) { int temp = Math.min(v / i , n); count += temp; } return count; } }
然后有人说这道题抄了codeforces:
This exact problem is found on the Codeforces OJ on this link:
http://codeforces.com/contest/448/problem/D
Its solution is also fully written on stack overflow on this link:
https://stackoverflow.com/questions/33464901/using-binary-search-to-find-k-th-largest-number-in-nm-multiplication-table
I found several people who blindly copied that code and got AC!. The reason I know this problem was on Stackoverflow was because Iwas the one who asked that question in 2015!!
相关文章推荐
- LeetCode Weekly Contest 47解题思路
- LeetCode Weekly Contest 8 第八周周赛
- LeetCode Weekly Contest 51
- LeetCode 660 Remove 9 (LeetCode Weekly Contest 45)
- (几何)LeetCode Weekly Contest 32 D-Erect the Fence
- 【LeetCode Weekly Contest 26 Q1】Longest Uncommon Subsequence I
- LeetCode Weekly Contest 13-Matchsticks to Square【中】
- LeetCode Weekly Contest 34解题思路
- LeetCode Weekly Contest 48解题思路
- LeetCode Weekly Contest 37解题思路
- LeetCode Weekly Contest 24 之 538.Convert BST to Greater Tree
- LeetCode Weekly Contest 24 之 542.01 Matrix
- LeetCode Weekly Contest 30
- (dp)LeetCode Weekly Contest 34 -Non-negative Integers without Consecutive Ones
- leetcode Weekly Contest 67 -- 763. Partition Labels
- LeetCode 650 2 Keys Keyboard - LeetCode Weekly Contest 43
- LeetCode Weekly Contest 52 Longest Univalue Path(链表dfs)
- LeetCode Weekly Contest 9 第九周周赛
- LeetCode Weekly Contest 64 - 752. Open the Lock【BFS + string】
- LeetCode Weekly Contest 28