LeetCode刷题2-火柴拼正方形
前言
经常遇到这样的问题
dfs算法?bfs又是啥?
怎么枚举所有可能性?
题目描述:
你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须 使用一次 。
如果你能使这个正方形,则返回 true ,否则返回 false 。
示例代码:
class Solution { public boolean makesquare(int[] matchsticks) { // 当matchsticks数组长度小于等于3时(火柴数量小于等于3),无法拼成正方形 if(matchsticks.length <= 3){ return false; } // 所有火柴长度求和必须为4的倍数,不然无法拼成正方形 int totalLen = Arrays.stream(matchsticks).sum(); if (totalLen % 4 != 0) { return false; } // 先用Arrays.sort从小到大排序,再从大到小排序,减少搜索量 Arrays.sort(matchsticks); for (int i = 0, j = matchsticks.length - 1; i < j; i++, j--) { int temp = matchsticks[i]; matchsticks[i] = matchsticks[j]; matchsticks[j] = temp; } // 存放4条边 int[] edges = new int[4]; // 给dfs传入的参数分别是:索引、matchsticks数组、存放边长的edges数组,边长的长度(由总长度除以4得到) return dfs(0, matchsticks, edges, totalLen / 4); } public boolean dfs(int index, int[] matchsticks, int[] edges, int len) { if (index == matchsticks.length) { return true; } // 开始循环遍历edges数组并赋值(因为matchsticks数组已经从小到大排序好,直接把matchsticks数组中的元素一个个累加进去,在if判断时递归),经过递归的处理,它能让edges数组上的元素和边长(len)相等 for (int i = 0; i < edges.length; i++) { edges[i] += matchsticks[index]; if (edges[i] <= len && dfs(index + 1, matchsticks, edges, len)) { return true; } edges[i] -= matchsticks[index]; } // 上面的步骤中没有走到return true,说明不能用所有火柴拼成正方形 return false; } }
执行结果:
开始这个题目对我来说真的难度还是挺大的,尤其对于DFS-深度优先搜索不太清楚的我。接下来,我们先讲讲DFS一些东西。便于更好的理解这道题目解法。
大O标记法-时间复杂度(Time Complexity):
O(1) 常数
public static void main(String[] args) { int n = 10; System.out.println("hello n = " + n); }
O(log n) 对数
对数公式是数学中的一种常见公式,如果a^x=N(a>0,且a≠1),则x叫做以a为底N的对数,记做x=log(a)(N),其中a要写于log右下。其中a叫做对数的底,N叫做真数 。通常我们将以10为底的对数叫做常用对数,以e为底的对数称为自然对数。
public static void main(String[] args) { int n = 1024; int count = 1; for (int i = 1; i <= n; i = i * 2) { System.out.println("第" + count + "次循环"); System.out.println("hello i = " + i); count++; } }
运行结果:
简单这样理解:之前需要运行N次才能完成,现在(i=i*2)我只需要运行logN次就能结束了
O(n) 线性
public static void main(String[] args) { int n = 10; for (int i = 1; i <= n; i++) { System.out.println("hello i = " + i); } }
O(n^2) 平方
public static void main(String[] args) { int n = 10; for (int i = 1; i <= n; i++) { System.out.println("hello i = " + i); for (int j = 1; j <= n; j++) { System.out.println("hello j = " + j); } } }
O(n^3) 立方
public static void main(String[] args) { int n = 10; for (int i = 1; i <= n; i++) { System.out.println("hello i = " + i); for (int j = 1; j <= n; j++) { System.out.println("hello j = " + j); for (int k = 1; k <= n; k++) { System.out.println("hello k = " + k); } } } }
O(2^n) 指数
public static void main(String[] args) { int n = 2; int count = 1; for (int i = 1; i <= Math.pow(2, n); i++) { System.out.println("第" + count + "次循环"); System.out.println("hello i = " + i); count++; } }
O(n!) 阶乘
广度优先搜索(Breadth First Search)
(37条消息) 【算法入门】广度/宽度优先搜索(BFS)_raphealguo的博客-CSDN博客_bfs算法
深度优先搜索(Depth First Search)
(37条消息) java实现-深度优先搜索_Longtermevolution的博客-CSDN博客_java深度优先搜索
本文来自博客园,作者:chch213,转载请注明原文链接:https://www.cnblogs.com/chch213/p/16341540.html