近来走上了Leetcode刷题之路,不过刷题背后更重要的是思路,掌握了方法,举一反三融会贯通。故在此我总结每道题的解题思路,这篇博客只涵盖Easy模式的题目,并按照题目从简单到难的顺序来列举。Medium和Hard模式的请见我另外2篇博客。
344 Reverse String,最近新加的一道题,用C++秒过,12秒,反转字符串,思路很简单,一种暴力方法就用直接用一个新的字符串存储,然后一个一个从后往前遍历旧的字符串。第二种就是原地用2个指针从两端往中间扫描,当left指针小于right指针时,就交换两个下标对应的值,否则就跳出循环。两种方法都是12ms过。同学用java做的时候遇到了坑,time limit exceed,好像是对于回车换行的情况,java的string支持的不行。只能先用toCharArray转换为用char数组,然后就好了。
292 Nim Game,传说中的一行代码搞定。属于很简单的博弈推理。
思路:假如只有1~3个石头,那我方肯定能赢,假若有4个石头,无论我取1~3个石头,对方总是能拿下最后一个石头,所以这时候我方必输。假若有5~7个石头,我能取对应的1~3个石头使得敌方处于只剩4个石头的状态(敌方必输)。假若有8个石头,则无论我取无论我取1~3个石头,对方总是能使得我处于只剩4个石头的状态(我方必输)。以此类推,不难得出,当石头数量为4的倍数时,我方必输。否则,我方必赢。
266 Palindrome Permutation ,题目如下:
思路:一开始可能会想着去生成所有的permutation,然后逐个枚举看有没有回文串。How Stupid!受到博客http://www.cnblogs.com/yrbbest/p/5021398.html的启发,
新思路如下:用一个集合set,逐个遍历这个字符串,如果便利到一个字母在set中没有的话,就加到set里,如果set里出现过这个字母,就把那个字母移出set。遍历结束时,如果set里的元素大于等于2的话,那就说明无法生成回文串。否则返回True。其实道理很简单,11122能形成回文串而111222则不能。这个思路其实跟括号匹配有点相似。其实set里剩下元素为0个的时候,回文串长度为偶数,set里剩下的元素只有1个的时候,回文串长度为奇数。
293 Flip Game
思路:http://blog.csdn.net/dolphin_wby/article/details/50336883
258 Add Digits
思路:一开始也会想着暴力模拟,但是显然有更好的方法,这道题应该属于数论,受到https://en.wikipedia.org/wiki/Digital_root的启发,我发现了一个如下的公式可以用来直接计算得到结果:
104 Maximum Depth of Binary Tree
思路:其实求二叉树的最大深度,就用递归,直接return 1 + max(DFS(left), DFS(right))就行,注意当节点为NULL的时候return 0
237 Delete Node in a Linked List
1 -> 2 -> 3 -> 4
变成1 -> 2 -> 4
思路:给定一个node,要删掉它,那我就把这个node的下一个node的value赋值给这个要删除的node,然后把这个node的next指针指向下一个node的下一个node就行了。
226 Invert Binary Tree
思路:递归&非递归版本
283 Move Zeroes
思路:双指针压缩法:实际上就是将所有的非0数向前尽可能的压缩,最后把没压缩的那部分全置0就行了。比如103040,先压缩成134,剩余的3为全置为0。过程中需要一个指针记录压缩到的位置。(参考:点击打开链接)
空间复杂度为O(1),因为是就地解决的,时间复杂度为O(N)
100 Same Tree
思路:判断两棵树是否是等价的,有递归和非递归版本:点击打开链接
递归就是(1)若2棵树都是NULL,则返回true(2)若一棵树为空一棵树非空,则返回false(3)若两棵树都非空,则看下val是否相等,若val不相等则返回false。若val相等则return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
非递归的就是利用2个queue进行层次遍历,每次进队的时候,把2个node拿来比较一下看是否相等,如果不等就return false
242 Valid Anagram
思路:2种方法
217 Contains Duplicate
171 Excel Sheet Column Number
思路:26进制转10进制
169 Majority Element
思路:一个简单的方法就是对数组排序,然后下标为n/2的元素就是要返回的值,因为注意到题目说肯定有一个元素出现的次数超过一半,那么排序后那个元素肯定会出现在正中间(可证明),时间复杂度就是排序复杂度O(nlogn)
当然还有更好的线性算法:每次从数组中找出一对不同的元素,将它们从数组中删除,直到遍历完整个数组。由于这道题已经说明一定存在一个出现次数超过一半的元素,所以遍历完数组后数组中一定会存在至少一个元素。Moore voting algorithm--每找出两个不同的element,就成对删除即count--,最终剩下的一定就是所求的。时间复杂度:O(n)