自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(148)
  • 收藏
  • 关注

原创 LeetCode - 235. Lowest Common Ancestor of a Binary Search Tree

BST有一个特性,就是某个root结点的值大于左子树中所有结点的值,小于所有右子数结点的值。所以如果一个结点是另外两个节点的共同祖先,那么这个结点的值必然是在另外两个值之间,可以根据这个特性写出算法。另外一点常用的思维就是在遇到二叉树的问题的时候,常常需要用递归的思维解决问题。代码如下:/** * Definition for a binary tree node. * public cl

2016-07-05 10:00:30 248

原创 LeetCode - 106. Construct Binary Tree from Inorder and Postorder Traversal

这道题目的思路与上一题基本是一样的,就不再详细写出,代码如下:/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; }

2016-07-04 21:17:37 200

原创 LeetCode - 105. Construct Binary Tree from Preorder and Inorder Traversal

首先,当我们遇到Binary Tree相关的问题的时候,要考虑使用递归是否可以解决问题,这是一个常用的思路。接下来我们来看一下这道题目,给出了一个binary tree的preorder, inorder traversal,根据前序遍历和中序遍历的性质,我们知道preorder的第一个元素必然是树的root,接着我们在inorder这个数组中找到root的index,那么root左侧的都是左

2016-07-04 20:53:03 295

原创 LeetCode - 8. String to Integer(atoi)

实在不明白为什么这道题目是easy....确实没做出来,看了别人的解法之后也觉得自己这么渣...估计再来也还是要跪,没什么说的了...背下来吧,而且这个代码写得挺好看,如下:public class Solution { public int myAtoi(String str) { if(str == null || str.length() == 0) return

2016-07-04 18:41:47 190

原创 LeetCode - 50. Pow(x, n)

这道题的一开始的想法是直接乘,时间复杂度为O(n),结果果然在LeetCode上面TLE了。更快的算法是使用divide and conquer的思想:首先解决特殊值:如果n == 0,直接返回1;如果x == 0,直接返回0;对于其他的情况,如果n是奇数,那么return x * myPow(x * x, n / 2);如果n是偶数,那么return myPower(x * x,

2016-07-04 17:34:18 303

原创 LeetCode - 43. Multiply Strings

这个过程主要分为三步,首先不进位地将两个数字相乘,这里有两点需要注意:第一,两个数字相乘,得到结果的位数最多为这两个数字的位数相加;第二,来自这两个数字的某两位的数字相乘,反映到结果的位上是products[i + j + 1]。其次从右向左,逐个进位,最后使用StringBuilder构造答案,注意删除左侧前面所有的0,同时也要考虑如果相乘的两个数为0和0的情况。时间复杂度为O(m * n),代

2016-07-04 16:23:32 213

原创 LeetCode - 234. Palindrome Linked List

一开始思考的方式同样是使用Stack,但是这样并没有满足题目要求的利用constant space,所以这里的想法是使用fast runner/slow runner找到Linked List的中间部位,然后反转后面的部分,进而进行比较。一个很好的分析如下图:注意这里有个小技巧,就是当fast != null的时候将slow指向slow.next,这样可以保证后面反转的部分是比较短的,

2016-07-04 15:27:05 277

原创 LeetCode - 125. Valid Palindrome

关于Palindrome的问题,一般可以用两类解法,第一类是使用Stack反向存储内容,然后再和正向的比较;第二类是使用两个指针,一开始一个设置在开头,一个设置在尾部,依次进行比较。这道题目另外有些要求,就是如不不是数字或字母的话就跳过,所以正好可以使用Java内置的Character.isLetterOrDigit()函数进行判断,如果不是的话则head++/tail--,但是注意在这种情况下要

2016-07-04 11:39:02 240

原创 LeetCode - 67. Add Binary

将两个以String表示的二进制数从低位逐个相加,使用一个carry变量循环记录每一位相加的进位,并且在循环相加下一位的时候把carry也加进来。把String中的char变成数字的方式非常巧妙,使用ASCII编码的特性,用每一位的char减去'0',得到的就是这个char所对应的数字。这道题目体现了很好的循环相加的思想,需要记一下。时间复杂度为O(max(m, n)),代码如下:public

2016-07-04 10:09:54 276

原创 LeetCode - 66. Plus One

对数组表示的数字进行加一的处理,从最低位逐个检查这一位上的数字是否为9,如果小于9的话直接+1返回,如果大于9的话则把这一位设置为0继续检查下一位,如果把这个数组循环完毕之后都没有返回,则说明现在原来的数字每一位上面都是9。这时候需要另外用一个长度为n + 1的数组,将其最高位设置为1,直接返回即可。时间复杂度为O(n),代码如下:public class Solution{ publ

2016-07-04 09:15:33 249

原创 LeetCode - 111. Minimum Depth of Binary Tree

以前做过一道Maximum Depth of Binary Tree的题目,思想是使用divide and conquer的思想和recursion的方式,这次一开始的时候仍然按照那个方法去做,结果失败了。问题出在哪儿呢?考虑下面的情况:这时候如果按照原来那种写法的话,这个树的最低高度应该是2,但是Math.min(1, 0) + 1得到的结果为1,所以是不对的,要更加全面的考虑出现的

2016-07-03 21:40:12 298

原创 LeetCode - 92. Reverse Linked List II

这道题目的要求是reverse Linked List中间的某一段,所以自然而然地想到将Linked List看作三部分,第一部分和第三部分不动,只是反转第二部分。另外,由于Linked List的头节点可能发生变化,所以要用到dummyNode这一技巧。Rerverse Linked List这一方法在前面的题目中已经看到过,这里不再重复,其实这道题目并没有很难的地方'fan'fn

2016-07-03 18:58:31 179

原创 LeetCode - 103. Binary Tree Zigzag Level Order Traversal

在level order traversal的基础上进行一些小的修改即可,另外使用一个变量存储当前level的number,如果currLevelNumber % 2 == 0就正向访问当前level结点,否则反向访问当前level结点,反向访问的方式是使用ArrayList.add(0, E)。时间复杂度为O(n),n为二叉树中结点的数量,空间复杂度为O(n),代码如下:/** * Def

2016-07-03 17:47:03 176

原创 LeetCode - 107. Binary Tree Level Order Traversal II

其实这道题目没有太大的技术含量,只是在正常的level order traversal上面做了一些很小的变化。第一种方法就是在每一层遍历完毕之后向result添加这一层的结果时,从后面连续添加,也就是使用了ArrayList.add(0, E)方法,时间复杂度为O(n),n为二叉树的结点数量,代码如下:/** * Definition for a binary tree node. *

2016-07-03 17:29:37 234

原创 LeetCode - 102. Binary Tree Level Order Traversal

Binary Tree Level Order Traversal使用queue来实现,level order traversal也相当是一种bfs的算法。首先将root节点加入queue中,接下来当queue不为空的时候,先记录当前queue的size,也就是binary tree这一层的节点数量,接着将这一层的结点添加到结果中,在添加的同时检测结点的左右儿子是不是为空,如果不为空的话将其加入到

2016-07-03 16:59:26 321

原创 LeetCode - 367. Valid Perfect Square

一开始的想法是从1到n / 2 + 1逐个遍历,看i * i == n?但是这样写应该是无法通过LeetCode测试的,因为一般只要涉及到i * i的问题,LeetCode都会给出一个非常大的数字,让i * i几乎一定达到overflow的地步,所以这里的写法应该是Math.abs(n * 1.0 / i - i) public class Solution { public bool

2016-07-03 16:09:18 300

原创 LeetCode - 75. Sort Colors

第一种方法是基于计数排序的算法,需要对数组进行两遍的扫描,第一遍统计红,白和蓝的数目,第二遍生成新的数组。这种方法可以进行扩展,对于数组中数字范围已知的情况,都可以使用这种算法。时间复杂度为O(n),代码如下:第二种方法并不是很general,特别地对于这道题目适用。这种方法只对数组扫描一次,使用两个指针,分别指向red的最后一个元素和blue最前面的一个元素,i从0到第一个blue inde

2016-07-03 12:47:48 263

原创 LeetCode - 191. Number of 1 Bits

求出一个无符号数二进制表示中1的个数,这个题目首先想到的是将给出的数字变成二进制表示,并且每看到一个1,就将numberOfOne的数量加一。但是这种方法错误的,错误的原因就在于没有考虑题目中给出的无符号数的这个特性,原来循环中的写法是:if(n % 2 == 0) result++;n /= 2但这样是不对的,对于LeetCode上给出的测试用例0b10000000000000000

2016-07-03 11:51:03 200

原创 LeetCode - 278. First Bad Version

这道题目的解法没有什么难度,相当于是34. Search for a Range中的寻找左侧range,但是这道题目却有一个非常隐秘却又非常大的陷阱,就是在计算mid的时候。如果我们使用mid = (left + right) / 2的方法来计算mid的话,由于left和right都可能非常大,所以相加的结果可能会导致overflow,故而正确的写法是mid = left + (right - l

2016-07-03 09:52:33 290

原创 LeetCode - 34. Search for a Range

这道题目可以使用两次二分搜索来解决,第一次找到target的左range,第二次找到targe的右range。在第一次二分搜索中,我们分别将两个指针i和j设置为0和n - 1,根据nums[mid]和target的相对大小,我们有以下三种情况:1. nums[mid] 2. nums[mid] > target,那么target的左range在mid的左侧,故而需要更新指针j = mi

2016-07-03 09:12:54 375

原创 LeetCode - 148. Sort List

这道题分为三步,首先通过fast slow双指针的方法找到list中间的元素,其次将list分为两半分别对它们进行排序,最后将它们merge起来。注意这道题目同样使用了递归的思想,是merge sort的linked list版本。时间复杂度O(nlogn),代码如下:/** * Definition for singly-linked list. * public class ListN

2016-07-03 00:10:23 193

原创 LeetCode - 65. Valid Number

这道题目的条件描述非常不清晰,要求就是找出全部可能为数字的情况。由于自己太渣....这道题看了一会儿就放弃了,LeetCode Discuss上面有人的解法非常好,这里叙述一下他的思想,应该是基于正则表达式的。首先我们把给定的字符串前后的空格都去掉,因为无论前后有多少空格,只要它的主体部分是数字,我们也还是将它认为成数字。接下来进行

2016-07-02 21:04:44 321

原创 LeetCode - 268. Missing Number

一开始想到的思路是使用和来计算,首先我们通过公式将从1到n的和计算出来,因为给出的数组中少了一个元素,所以我们再计算一下给出的数组的和,用1到n的和减去给出的数组的和,就得到了结果。时间复杂度为O(n),代码如下:public class Solution { public int missingNumber(int[] nums) { if(nums == null

2016-07-02 20:35:09 707

原创 LeetCode - 371. Sum of Two Integers

在不准使用+和-的情况下实现两个整数的加法,那么肯定要用到位运算了。我们考虑位运算加法的四种情况:0 + 0 = 01 + 0 = 10 + 1 = 01 + 1 = 1(with carry)在学习位运算的时候,我们知道XOR的一个重要特性是不进位加法,那么只要再找到进位,将其和XOR的结果加起来,就是最后的答案。通过观察上面的四种情况我们可以发现,只有在两个加数的值都是1的

2016-07-02 11:22:22 4420 1

原创 LeetCode - 219. Contains Duplicate II

这道题目时间复杂度较高的方法比较容易想到,i从1到k,逐次检查相隔i的元素是否相等,但是这个必然不是最优的解法,代码不是很难,这里就不写了。着重要说的是第二种时间复杂度最差为O(n)的算法。这种算法使用了一种非常好的思想:sliding windows,也就是说我们从数组的开头开始迭代,并且将设置一个大小从i到i + k总共k + 1个元素的sliding windows,每次继续迭代的时候,

2016-07-02 10:47:27 277

原创 LeetCode - 11. Container With Most Water

一个一开始都能想到的方法是对于每种可能的container,计算其容量,然后找到最大的那个,时间复杂度为O(n^2),当然这种方法肯定不是最优解,我们需要问自己can we do better?注意到这里最耗时的操作主要是scan数组并且尝试各种可能的container,那么我们能不能使用更加smart的scan方法来降低时间复杂度呢?实际上是可以的,我们使用两个pointer,初始分别指向数

2016-07-01 21:05:58 279

原创 LeetCode - 21. Merge Two Sorted Lists

使用两个指针,开始的时候分别指向两个sorted lists的开头,并且初始化一个dummyNode,然后迭代比较这两个指针指向的val,将比较小的那个放到dummyNode开头的list的后面,当退出循环之后还要检测下哪个list没有被完全迭代完毕,继而继续迭代,时间复杂度O(m + n),空间复杂度constant,代码如下:/** * Definition for singly-lin

2016-07-01 14:54:08 212

原创 LeetCode - 88. Merge Sorted Array

从前面移动元素的话会非常麻烦,所以这道题目的思路是从数组的后面开始移动元素,将两个数组从大到小移动而不是从前面从小到大移动,这种方法非常巧妙,也是一种常用的方法,每当从前面移动数组或字符串不是很方便的时候可以思考可否从数组的后面进行移动。另外当某个数组的元素全都移动完毕之后,我们需要将另一个数组剩下的元素进行移动,这里利用了题目的一个特性,就是我们移动元素的目标是nums1,也就是说,如果nums

2016-07-01 11:25:47 270

原创 LeetCode - 229. Majority Element II

这道题目是Moore Voting Algorithm的变体,找到数组中出现次数大于n / 3(int算法)的元素,注意到这里说的是严格的大于,所以这样的数字最多有两个。第一次遍历的时候使用Moore Sorting Algorithm找出两个可能为众数(概念不严格,借用一下)的数字,然后再进行第二次遍历进行检查它们出现的次数是不是大于n / 3,注意到题目中并没有说明一定会出现两个众数,所以在第

2016-07-01 10:42:50 461

原创 LeetCode - 169. Majority Element

第一种方法非常简洁,虽然时间复杂度并不是最小的,为O(nlogn),直接对数组进行排序,然后返回nums[n / 2]即可,代码如下:public class Solution { public int majorityElement(int[] nums) { Arrays.sort(nums); return nums[nums.length / 2

2016-06-30 23:03:56 262

原创 LeetCode - 142. Linked List Cycle II

一开始的思路和141. Linked List Cycle是一样的,当slow == fast的时候说明有环,接下来看这张图:代码如下:/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) {

2016-06-30 22:20:08 160

原创 LeetCode - 141. Linked List Cycle

检测一个linked list里是否有环,思想就是使用两个移动速度不同的指针,fast = fast.next.next; slow = slow.next;在每一步前进的时候,如果fast == null或者fast.next == null,那么说明没有环,如果slow == fast,说fast指针赶上了slow,说明有环,复杂度的分析和代码如下:/** * Definition

2016-06-30 21:31:41 188

原创 LeetCode - 153. Find Minimum in Rotated Sorted Array

O(n)和使用Arrays.sort(nums)的方法就不再写了。真是各种花式使用二分搜索啊...二分搜索的关键点在与left,right指针移动条件的判定,这道题目的判定条件非常巧妙。使用nums[mid]和nums[n - 1]进行比较,如果nums[mid]比较大的话,那么说明mid这个元素必然在rotated part里面,而最小的元素必然是rotated part后面的一个元素,所以le

2016-06-30 18:27:28 277

原创 LeetCode - 73. Set Matrix Zeros

参考CC 150 1.7一开始看起来这道题好像是很简单,遍历整个矩阵,发现0元素之后就将这个元素所在的行和列都设置成0,但是这样做的是错的,因为在读取被清零的行或者列的时候,读到的都是0,很快整个矩阵的所有元素都会变成0。避开上面问题的方法是新建一个矩阵标记0元素的位置,然后在第二次遍历的时候将0元素所在的行和列清零,这种方法的空间复杂度是O(MN)。但是仔细想一下,我们实际上并不需要

2016-06-30 17:25:31 604

原创 LeetCode - 7. Reverse Integer

这道题目看似简单,但是有一个int溢出的问题需要考虑,故而在每一步迭代计算result的时候,都要检测是否超过了Integer.MAX_VALUE,但是在result已经大于Integer.MAX_VALUE的时候检测是不行的,因为这时候result已经溢出,成为负数。故而应该在计算前检测result和(Integer.MAX_VALUE - x % 10) / 10的关系,如果大于的话就说明接下

2016-06-30 13:22:05 230

原创 LeetCode - 69. Sqrt(x)

方法一:Binary Search这道题目是一个典型的binary search问题,看似比较简单,但其实陷阱也不少。一开始直接从1到x使用binary search来寻找答案,但结果竟然TLE了,仔细想想可以发现,我们并不用从1到n寻找,只用从1到n / 2 + 1就可以了,这样就省掉了一半的时间,妈妈再也不用担心我TLE啦!可是在LeetCode上遇到x很大的test case的时候,结果

2016-06-30 11:53:17 317

原创 LeetCode - 240. Search a 2D Matrix II

矩阵中两行或者两列之间的元素的大小并没有一定的规律,所以二分法不太好用,直接用74. Search a 2D Matrix的解法二即可,时间复杂度为O(n + m),代码如下:public class Solution { public boolean searchMatrix(int[][] matrix, int target) { if(matrix == nul

2016-06-30 11:09:15 317

原创 LeetCode - 74. Search a 2D Matrix

解法一:又是查找,又是已经排序的数组,所以很容易想到使用二分查找来处理这个问题,首先使用第一次二分查找找到元素所在的row,再用第二次二分查找找到row中的元素,另外在写程序的时候要注意相等时的判断,以及边界条件的处理。还有一个需要考虑的问题就是,二分查找更多的在于一种思想,而并不单单是从已排序的数组中寻找元素的算法,比如这道题目使用第一次二分查找的时候可能无法在每一行的第一个元素中找到tar

2016-06-30 10:31:47 281

原创 LeetCode - 260. Single Number III

在Single Number的基础上,只出现一次的数字从一个变成了两个,同样地我们仍然希望使用xor的技巧来方便地得到两个只出现一次的数字,所以我们需要思考一种方法将给出的数字分为两堆,每堆含有的除了一个只出现一次的数字之外,其他都是出现两次的数字。这样我们就可以在这两堆上分别进行xor得到两个值。这里我们采用的方法是首先对所有的数字进行xor,得到的值也就是两个只出现一次的数字的xor值,接

2016-06-30 08:38:25 296

原创 LeetCode - 86. Partition List

这道题的思路是先初始化两个list,然后遍历原来的list,发现小于x的分到小的list,反之分到大的list,然后将两个list merge一下,注意头和尾,时间复杂度O(n),空间复杂度O(n),代码如下:/** * Definition for singly-linked list. * public class ListNode { * int val; * L

2016-06-29 22:59:28 223

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除