leadcode的Hot100系列--78. 子集--回溯】的更多相关文章

上一篇说了使用位运算来进行子集输出,这里使用回溯的方法来进行排序. 回溯的思想,我的理解就是: 把解的所有情况转换为树或者图,然后用深度优先的原则来对所有的情况进行遍历解析. 当然,因为问题中会包涵这各种各样的限制条件,我们可以用这些限制条件去减少遍历的分支. 其实,比较著名的就是0-1背包问题,这个背包问题之后再说,这里先看排列组合. 假设我们的数组为[6,7,8],依然使用0来表示当前数字不存在,用1来表示当前数字存在,我们就可以画出这样一个树: 这里使用递归来生成对应的flag标记,重点是…
看一个数组的子集有多少,其实就是排列组合, 比如:[0,1] 对应的子集有:[] [0] [1] [1,1] 这四种. 一般对应有两种方法:位运算 和 回溯. 这里先使用位运算来做. 位运算 一个长度为n的数组,对其做排列组合,可以理解为:这n个数字中,有哪些是存在的,哪些是不存在的. 例如,数组为[1,2,3],可以组合为:[1,2],则说明1和2是存在的,3是不存在的, 我们可以这么规定一下: 用1标记为存在,0标记为不存在, 那么[1,2]这个组合就可以用 110来标记,[1,3]的组合就…
提交leetcode的时候遇到了问题,一直说访问越界,但仔仔细细检查n多遍,就是检查不出来. 因为我用到了count全局变量,自加一来表明当前数组访问的位置, 后来突然想到,是不是在leetcode在运行测试用例的时候,是连续测试的,用的同一个上下文,这样的话,就没有对这个全局变量清零-- 果然,清零之后就可以了--已经3:47了,这里先上代码,明天再详细说吧-- 今天更新一下这道题的思路. 可以先参考一下之前的两篇文章,循序渐进,好理解一些: leadcode的Hot100系列--78. 子集…
如果这个: leadcode的Hot100系列--62. 不同路径--简单的动态规划 看懂的话,那这题基本上是一样的, 不同点在于: 1.这里每条路径相当于多了一个权值 2.结论不再固定,而是要比较不同走法哪个权值更小 针对第一点,需要把第一行和第一列的权值做一个累加: 假设这里的权值都是1,则 A B C D E F G H I J K L 中,f(A) 为1,f(B) 就为2,,因为A和B各有一个权值,f(C)为3,f(E) 为2,f(I)为3: 1 2 3 4 2 f(F) f(G) f(…
描述 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3]输出:[ [3],  [1],  [2],  [1,2,3],  [1,3],  [2,3],  [1,2],  []] 解析 和求字符串的全排序思路一样,回溯.只不过终结条件不一样. 代码 List<List<Integer>> list = new ArrayList<>(); public List<…
题目比较清晰,简单来说就是: A B C D E F G H I J K L 只能往右或者往下,从A到L,能有几种走法. 这里使用动态规划的方法来做一下. 动态规划最重要的就是动态方程,这里简单说下这个动态方程怎么做出来的吧. 记 f(B) 为 A到B总共可以有的走法. 想知道f(L),那其实只要知道f(H)和f(K)就可以了. 因为从A到H之后,再想到L就只有一种方法,AK同理,所以 f(L) = f(H) + f(K). 那f(H)呢,就等于 f(D)+f(G),这里就很容易得到他的动态方程…
栈:先入后出,后入先出 像电梯一样,先进入电梯的,走到电梯最深处,后进入电梯的,站在电梯门口, 所以电梯打开的时候,后进入的会先走出来,先进入的会后走出来. push,对应入电梯,把数据往里面压 pop, 对应出电梯,把数据往外拿 栈顶,对应电梯门口 栈底,对应电梯最深处 这里使用链表实现栈. 先创建一个MinStack头, 入栈:直接把结构体挂在MinStack头后面, 出栈:直接拿出MinStack头后面的结构体. 取最小值:对链表进行一次遍历,返回最小值. typedef struct m…
这里使用两种方式, 一个是直接从头往后遍历 -------> 迭代 一个是从最后一个往前遍历 -----> 递归 迭代 定义三个变量:pPre pNext pNow pPre表示当前节点的前一个地址,pNext表示当前节点的下一个地址,pNow表示当前节点的地址. 反转的核心:就是把 pNow的next指针,指向 pPre 因为反转之后,pNow的next原来的值会丢,所以在反转之前,要用pNext把原来的值保存一下. 反转之后,要处理下一个节点,而本节点就是下一个节点的前一个节点,所以用pP…
依然使用递归思想. 思路: 1.树的深度 = max (左子树深度,右子树深度)+ 1 . ------> 这里的加1是表示自己节点深度为1. 2.如果当前节点为null,则说明它的左右子树深度为0. int max(int a, int b) { if (a>b) return a; else return b; } int maxDepth(struct TreeNode* root){ int iDepth = 0; if (NULL == root) return 0; iDepth…
这玩意儿基本上还是遍历的那一套, 这里使用先序遍历的方式,直接对左右子树进行对调即可. (虽然看题目的时候,感觉都一样,但真正写出来之后,印象还是深刻了很多) struct TreeNode* invertTree(struct TreeNode* root){ struct TreeNode *pTemp = NULL; if (NULL == root) return NULL; pTemp = root->left; root->left = root->right; root-&…