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 ...
随机推荐
- 疑问:line-height对非文字行内块的影响
line-height:对子元素是非文字的行内块,表现出来的不是垂直居中.目前还不知道具体细节. 可以看出来两个东西不在一行.老师的解释是line-height对非文字元素解释不一样,但是我没懂细节. ...
- .NET Oracle Developer的福音——ODP.NET Managed正式推出
在.NET平台下开发Oracle应用的小伙伴们肯定都知道一方面做Oracle开发和实施相比SqlServer要安装Oracle客户端(XCopy.自己提取相关文件也有一定复杂性),另一方面相比JAVA ...
- yy_model及 YYLabel
一, yy_model 1.yy_model 可以存放包含数组的属性,调用方法如下: + (NSDictionary *)modelCustomPropertyMapper { return @{@& ...
- Daikon Forge GUI Library(dfgui)之Event Binding
点击按钮并弹出对话框,就用下面的大问题按钮吧 1,选中按钮,Component/Daikon Forge/Data Binding/Event Binding 2,UI上创建DfPanel,并将其Be ...
- HTML语法大全
卷标 , 属性名称 , 简介 002 <! - - ... - -> 批注 003 <!> 跑马灯 004 <marquee>...</marque ...
- Learn JavaScript(面向对象的程序设计01)
最新更新请访问: http://denghejun.github.io JavaScript与OOP JavaScript作为web前端一种重要的脚本技术,已被大多开发人员所熟知.compare ...
- 四则运算之Right-BICEP测试
Right-结果是否正确? 正确 B-是否所有的边界条件都是正确的? Conformance(一致性):值是否和预期的一致 是一致的 Ordering(顺序性):值是否如应该的那样 是 是有序或者无 ...
- poj1664-放苹果(递归)
一,题意: M个苹果放在N个盘子里,允许有盘子空着,问共有多少种不同的分法. 二,思路: 递归的思想求解: 1,有反复执行的过程(调用本身) 第一种情况n>m : 必定有 n-m 个盘子空着,去 ...
- CSS3过渡、变形和动画
1.CSS3过渡 所谓CSS3过渡,就是使用CSS3让元素从一种状态慢慢转换到另一种状态.如鼠标的悬停状态就是一种过渡.如下例子: #content a{ text-decoration: n ...
- c++代码中,使用svn版本号作为程序版本号的实现方法
1.编写版本模板文件 #ifndef _VERSIONSVN_H_#define _VERSIONSVN_H_#define VER_REVISIONSVN $WCREV$#endif //!_VER ...