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 ...
随机推荐
- poj 1141 Brackets Sequence (区间dp)
题目链接:http://poj.org/problem?id=1141 题解:求已知子串最短的括号完备的全序列 代码: #include<iostream> #include<cst ...
- dos2unix对shell脚本程序的解救
删除多个文件,不询问是否删除:rm -rf *.log (利用通配符) dos2unix 文件名:由于windows系统中文件的结束符和linux下文件的结束符不同,一些对语法要求较严格的脚本语言就会 ...
- 缓存依赖中cachedependency对象
缓存依赖主要提供以下功能:1.SQL 缓存依赖项可用于应用程序缓存和页输出缓存.2.可在 SQL Server 7.0 及更高版本中使用 SQL 缓存依赖项.3.可以在网络园(一台服务器上存在多个处理 ...
- 【BZOJ1076】[SCOI2008]奖励关 状压DP+期望
[BZOJ1076][SCOI2008]奖励关 Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须 ...
- BlockCanary 一个轻量的,非侵入式的性能监控组件(阿里)
开发者博客: BlockCanary — 轻松找出Android App界面卡顿元凶 开源代码:moduth/blockcanary BlockCanary对主线程操作进行了完全透明的监控,并能输出有 ...
- Django分析之导出为PDF文件
最近在公司一直忙着做exe安装包,以及为程序添加新功能,好久没有继续来写关于Django的东西了….难得这个周末清闲,来了解了解Django的一些小功能也是极好的了~ 那今天就来看看在Django的视 ...
- Shader实例:边缘发光和描边
效果图: 1.边缘发光 思路:用视方向和法线方向点乘,模型越边缘的地方,它的法线和视方向越接近90度.点乘越接近0 那么用 1-减去上面点乘的结果,来作为颜色分量,来反映边缘颜色强弱. Shader ...
- JavaScript必须了解的知识点总结【转】
整理的知识点不全面但是很实用. 主要分三块: (1)JS代码预解析原理(包括三个段落): (2)函数相关(包括 函数传参,带参数函数的调用方式,闭包): (3)面向对象(包括 对象创建.原型链,数据类 ...
- Ubuntu14.04安装微软雅黑字体
1.首先获得一套“微软雅黑”字体库(自行百度),包含两个文件msyh.ttf(普通)、msyhbd.ttf(加粗);2.在/usr/share/fonts目录下建立一个子目录,例如win,命令如下: ...
- 第 5 章 基础 DOM 和 CSS 操作
在常规的 DOM 元素中,我们可以使用 html()和 text()方法获取内部的数据.html()方法 可以获取或设置 html 内容,text()可以获取或设置文本内容. $('#box').ht ...