Leetcode: Matchsticks to Square && Grammar: reverse an primative array
Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match girl has, please find out a way you can make one square by using up all those matchsticks. You should not break any stick, but you can link them up, and each matchstick must be used exactly one time. Your input will be several matchsticks the girl has, represented with their stick length. Your output will either be true or false, to represent whether you could make one square using all the matchsticks the little match girl has. Example 1:
Input: [1,1,2,2,2]
Output: true Explanation: You can form a square with length 2, one side of the square came two sticks with length 1.
Example 2:
Input: [3,3,3,3,4]
Output: false Explanation: You cannot find a way to form a square with all the matchsticks.
Note:
The length sum of the given matchsticks is in the range of 0 to 10^9.
The length of the given matchstick array will not exceed 15.
DFS, my solution is to fill each edge of the square one by one. DFS to construct the 1st, then 2nd, then 3rd, then 4th. For each edge I scan all the matches but only pick some, the others are discarded. These brings about two disadvantages: 1. I need to keep track of visited elem. 2. after the 1st edge is constructed, I have to re-scan to make the 2nd, 3rd, 4th, thus waste time! So my code get TLE in big case
public class Solution {
public boolean makesquare(int[] nums) {
if (nums==null || nums.length==0) return false;
int sideLen = 0;
for (int num : nums) {
sideLen += num;
}
if (sideLen % 4 != 0) return false;
sideLen /= 4;
return find(nums, sideLen, 0, 0, new HashSet<Integer>());
}
public boolean find(int[] nums, int sideLen, int completed, int curLen, HashSet<Integer> visited) {
if (curLen > sideLen) return false;
if (curLen == sideLen) {
completed++;
curLen = 0;
if (completed==4 && visited.size()==nums.length) return true;
if (completed==4 && visited.size()<nums.length) return false;
}
for (int i=0; i<nums.length; i++) {
if (!visited.contains(i)) {
visited.add(i);
if (find(nums, sideLen, completed, curLen+nums[i], visited))
return true;
visited.remove(i);
}
}
return false;
}
}
Better Solution: DFS, but only scan all the matches once! If a match can not make the 1st edge, then we do not discard it, we try 2nd, 3rd, 4th edge
referred to: https://discuss.leetcode.com/topic/72107/java-dfs-solution-with-explanation
public class Solution {
public boolean makesquare(int[] nums) {
if (nums == null || nums.length < 4) return false;
int sum = 0;
for (int num : nums) sum += num;
if (sum % 4 != 0) return false;
return dfs(nums, new int[4], 0, sum / 4);
}
private boolean dfs(int[] nums, int[] sums, int index, int target) {
if (index == nums.length) {
if (sums[0] == target && sums[1] == target && sums[2] == target) {
return true;
}
return false;
}
for (int i = 0; i < 4; i++) {
if (sums[i] + nums[index] > target) continue;
sums[i] += nums[index];
if (dfs(nums, sums, index + 1, target)) return true;
sums[i] -= nums[index];
}
return false;
}
}
Updates on 12/19/2016 Thanks @benjamin19890721 for pointing out a very good optimization: Sorting the input array DESC will make the DFS process run much faster. Reason behind this is we always try to put the next matchstick in the first subset. If there is no solution, trying a longer matchstick first will get to negative conclusion earlier. Following is the updated code. Runtime is improved from more than 1000ms to around 40ms. A big improvement.
public class Solution {
public boolean makesquare(int[] nums) {
if (nums==null || nums.length<4) return false;
int sideLen = 0;
for (int num : nums) {
sideLen += num;
}
if (sideLen % 4 != 0) return false;
sideLen /= 4;
Arrays.sort(nums);
reverse(nums);
return find(nums, new int[4], 0, sideLen);
}
public boolean find(int[] nums, int[] edges, int index, int sideLen) {
if (index == nums.length) {
if (edges[0]==sideLen && edges[1]==sideLen && edges[2]==sideLen)
return true;
else return false;
}
for (int i=0; i<4; i++) {
if (edges[i]+nums[index] > sideLen) continue;
edges[i] += nums[index];
if (find(nums, edges, index+1, sideLen)) return true;
edges[i] -= nums[index];
}
return false;
}
public void reverse(int[] nums) {
int l=0, r=nums.length-1;
while (l < r) {
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
l++;
r--;
}
}
}
Grammar: How to sort array in descending order: http://www.java67.com/2016/07/how-to-sort-array-in-descending-order-in-java.html
How to sort object array in descending order
First, let's see the example of sorting an object array into ascending order. Then we'll see how to sort a primitive array in descending order. In order to sort a reference type array e.g. String array, Integer array or Employee array, you need to pass the Array.sort() method a reverse Comparator.
Fortunately, you don't need to code it yourself, you can use Collections.reverseOrder(Comparator comp) to get a reverse order Comparator. Just pass your Comparator to this method and it will return the opposite order Comparator.
If you are using Comparator method to sort in natural order, you can also use the overloaded Collection.reverseOrder() method. It returns a Comparator which sorts in the opposite of natural order. In fact, this is the one you will be using most of the time.
Here is an example of sorting Integer array in descending order:
Integer[] cubes = new Integer[] { 8, 27, 64, 125, 256 };
Arrays.sort(cubes, Collections.reverseOrder());
How to sort primitive array in descending order
Now, let's see how to sort a primitive array e.g. int[], long[], float[] or char[] in descending order. As I told, there are no Arrays.sort() method which can sort the array in the reverse order. Many programmers make mistake of calling the above Array.sort() method as follows:
int[] squares = { 4, 25, 9, 36, 49 };
Arrays.sort(squares, Collections.reverseOrder());
This is compile time error "The method sort(int[]) in the type Arrays is not applicable for the arguments (int[], Comparator<Object>)" because there is no such method in the java.util.Arrays class.
The only way to sort a primitive array in descending order is first to sort it in ascending order and then reverse the array in place as shown here. Since in place reversal is an efficient algorithm and doesn't require extra memory, you can use it sort and reverse large array as well. You can also see a good book on data structure and algorithm e.g. Introduction to Algorithms to learn more about efficient sorting algorithm e.g. O(n) sorting algorithm like Bucket sort.
Leetcode: Matchsticks to Square && Grammar: reverse an primative array的更多相关文章
- [LeetCode] Matchsticks to Square 火柴棍组成正方形
Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match ...
- Leetcode之深度优先搜索(DFS)专题-473. 火柴拼正方形(Matchsticks to Square)
Leetcode之深度优先搜索(DFS)专题-473. 火柴拼正方形(Matchsticks to Square) 深度优先搜索的解题详细介绍,点击 还记得童话<卖火柴的小女孩>吗?现在, ...
- leetcode面试准备:Kth Largest Element in an Array
leetcode面试准备:Kth Largest Element in an Array 1 题目 Find the kth largest element in an unsorted array. ...
- LeetCode 新题: Find Minimum in Rotated Sorted Array 解题报告-二分法模板解法
Find Minimum in Rotated Sorted Array Question Solution Suppose a sorted array is rotated at some piv ...
- 【LeetCode】961. N-Repeated Element in Size 2N Array 解题报告(Python & C+++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 日期 题目地址:https://leetcod ...
- 【LeetCode】153. Find Minimum in Rotated Sorted Array 解题报告(Python)
[LeetCode]153. Find Minimum in Rotated Sorted Array 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode. ...
- 【LeetCode】154. Find Minimum in Rotated Sorted Array II 解题报告(Python)
[LeetCode]154. Find Minimum in Rotated Sorted Array II 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...
- 【LeetCode】473. Matchsticks to Square 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 日期 题目地址:https://leetco ...
- LeetCode "473. Matchsticks to Square"
A trickier DFS, with a little bit complex recursion param tweak, and what's more important is prunin ...
随机推荐
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- Nginx二级域名及多Server反向代理配置
Nginx强大的正则表达式支持,可以使server_name的配置变得很灵活,如果你要做多用户博客,那么每个用户拥有自己的二级域名也就很容易实现了. 注:nginx反向代理同一ip多个域名,给head ...
- PHP遍历、删除文件夹中的所有文件
<?php header("Content-type:text/html;charset=utf-8"); /** * getDirFile 遍历文件夹中的所有文件 * @p ...
- ffmpeg 屏幕录制 so easy....
linux Linux下使用FFmpeg进行屏幕录制相对比较方便,可以使用x11grab,使用如下的命令: ffmpeg -f x11grab -s 1600x900 -r 50 -vcodec li ...
- 静态属性,直接把iis搞垮掉 Http error 503 Service Unavailable
属性有个好处,可以在get的时候做一些特殊处理,比如返回一个默认值,正是这个特性,吸引我讲静态字段修改了成静态属性,代码如下: public static string 微信订阅号 { get { i ...
- Self-introduction (自我介绍)
* 姓名,本名不想这样就暴露,Rachel我英文名,不愿意叫算了,直接叫我米蟲就好了. * 性格, 偏执一些,表里不一,表面和善,骨子倔强,我这一生都在追求高逼格,从未间断过 偶尔像个小疯子,有 ...
- Intersection of Two Linked Lists
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- 重置dns
flusdns
- php获得http头部信息的方法
$url = 'http://www.baidu.com'; $fp = fopen($url, 'r'); $meta_data = stream_get_meta_data($fp); var_d ...
- 使用MyBatis对表执行CRUD操作
一.使用MyBatis对表执行CRUD操作——基于XML的实现 1.定义sql映射xml文件 userMapper.xml文件的内容如下: <?xml version="1.0&quo ...