自定义博客皮肤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 - 13. Roman to Integer

首先将各个罗马字母所对应的数字放到一个HashMap里面,然后使用两个制针从String的最后一位开始向前扫描,位于大数的后面时就作为加数,位于大数的前面就当作减数,并且在扫描的过程中累加所得到的结果。代码如下:public class Solution { public int romanToInt(String s) { if(s == null || s.leng

2016-07-15 18:29:56 173

原创 LeetCode - 12. Integer to Roman

这道题目其实并没有什么太多可说的,因为罗马数字的写法本身就不了解,所以在discuss版看了看其他同学的解法。感觉这位同学的解法非常不错,很好的利用了%,/计算的性质和数组下标的性质。代码如下:public class Solution { public String intToRoman(int num) { String[] M = {"", "M", "MM",

2016-07-14 22:25:09 241

原创 LeetCode - 152. Maximum Product Subarray

这道题目的背景与上道题目53. Maximum Subarray比较相似,所以我们可以想到运用同样的子结构来求解问题,即maxProduct(nums, i)表示从nums[0]到nums[i],包括nums[i]的最大值。但是这道题目与上一道有一个非常不同的点是这道题目所要求的是乘法,也就是说两个绝对值很大的负数相乘也能得到很大的值,所以我们要针对这个情况做出一些改变:除了有一个变量记录最大值之

2016-07-14 10:18:47 201

原创 LeetCode - 53. Maximum Subarray

很明显地,这是一道优化的问题,通常情况下可以使用动态规划解决。而当谈及动态规划的时候,一件很重要的事情就是找出子问题的结构以及每个子问题的状态。一开始想到的子问题的结构为: maxSubArray(int nums[], int i, int j),它表示数组中num[i: j]的最大子数组,使用这种表示,我们的目标就是找出maxsubArray(nums, 0, nums.length -

2016-07-14 08:35:38 180

原创 LeetCode - 58. Length of Last Word

第一种方法是完全不用String所提供的库函数,首先使用一个指针i指向String的末尾,当i等于‘ ’的时候i--,跳过String尾部的‘ ‘,然后使用第二个指针j,令其等于i,然后当j指向的元素不为’ ‘的时候向前移动j,直到当前j指向’ ‘或者j == -1。此时要对j的情况进行判断,如果当前的j是指向’ ‘,那么最后一个单词的长度为i - j,如果i为-1的话,那么最后一个单词的长度

2016-07-13 23:08:42 258

原创 LeetCode - 90. SubsetsII

思路与40. Combination Sum II是一样的,连跳过重复的方式都一样,都是先进行排序然后在if语句中检测前面的相等元素是否已经作为调用的根节点进行过递归调用,代码如下:public class Solution { public List> subsetsWithDup(int[] nums) { List> list = new ArrayList>()

2016-07-13 22:24:22 645

原创 LeetCode - 78. Subsets

找到所有的XXX,这种题目都可以向DP和backtracking的方向去想,这道题和38, Combination Sum的解法基本是一样的,不同的是这道题目让返回所有的子集,所以在backtrack中不用进行检测,直接将当前的subset加入subsets中即可。另外这道题目也反映出了无剪枝的backtracking算法的运行情况,大约会调用2 ^ n次,代码如下:public class

2016-07-13 22:20:04 341

原创 LeetCode - 40. Combination Sum II

这道题目就是在上一道题目的基础之上进行的改动,不允许combination中出现重复的元素。在上一道题目中,对数组进行排序是不必要的,但是这道题目是必要的,因为题目接下来需要使用数组排序的这个性质跳过重复的元素,跳过的方法jij

2016-07-13 20:47:12 255

原创 LeetCode - 39. Combination Sum

这道题要求我们找出所有的可行解,一般这种问题我们可以考虑使用backtracking或DFS,通常情况下,我们将回溯法与DFS同等看待,可以用一个等式表示它们的关系:回溯法 = DFS + 剪枝。所以回溯法是DFS的延伸,其目的在于通过剪枝使得在DFS过程中如果满足了回溯条件不必找到叶子结点,就截断这条路径,从而加速DFS。实际上,即使没有剪枝,DFS从下层退回上层的时候也是一个回溯的过程,通常用

2016-07-13 20:03:02 630

原创 LeetCode - 38. Count and Say

题目中给了一个生成一系列字符串的方法,让我们找到这个系列中的第n个字符串。我们首先对生成字符串的方法进行分析和观察,发现第i + 1个字符串完全是在第i个字符串的基础上生成而来,和i之前的字符串都没有关系,所以我们可以把这道题目分解成两步来做:写出一个接受String作为参数并且生成下一个String的函数,然后再另外一个函数中调用这个函数n - 1次即可(因为第一个字符串是1,已经给出,所以产生

2016-07-13 18:04:01 204

原创 LeetCode - 36. Valid Sudoku

检测一个数独是否valid,注意数独是一个9 x 9的方格,在每一行每一列和每一个3 x 3的小正方形中,都必须出现从1到9的九个数字。由数独的性质而来,我们可以思考出检测一个数独是否valid的方法,就是分别对每一行每一列和每个3 x 3的小正方形进行检查,每一行每一列的检查方法较为容易,关键在于9个小正方形中数字的检查。这里我们用到了/,%运算的一些性质,对于一个从0-8的数字i,i /

2016-07-13 17:03:58 202

原创 LeetCode - 29. Divide Two Integers

这道题目要求我们在不适用乘除和模运算的情况先实现两个数的除法,那么这种情况下我们自然就会想到使用bit manipulation,我们来思考一下应该怎样使用bit manipulation:假设对于15和3的除法,其中15是被除数,3是除数。除法的本质就是计算在被除数当中有多少个除数,所以我们首先用15 - 3 = 12,结果大于3,那我们接下来就减去更多。因为不能使用乘法,所以我们将3进行左

2016-07-13 16:12:28 237

原创 LeetCode - 28. Implement strStr()

这道题目的本质就是在文本中搜索模式,我们使用一个指针i跟踪文本,一个指针j跟踪模式。对于每个i,代码首先将j重置为0并不断将它增大,直至找到了一个不匹配的字符或是模式结束(j == M)为止。如果在模式字符串结束之前文本字符串就已经结束了(i == N - M + 1),那么就没有找到匹配,模式字符串在文本中不存在。在最坏的情况下,暴力字符串查找算法在长度为N的文本中查找长度为M的模式需要~M

2016-07-13 15:30:46 172

原创 LeetCode - 24. Swap Nodes in Pairs

首先检测当前的Linked List是否为空或者只有一个结点,如果是的话就直接返回head。通过题目我们可以明显地看出Linked List的头指针会发生变化,所以这里我们使用dummyNode,接下来就是用三个指针prev, curr和next来交换两个相邻的结点,然后再更新指针的位置。注意在while循环的条件是curr != null && curr.next != null,前者是为了检测

2016-07-12 11:53:28 175

原创 LeetCode - 22. Generate Parentheses

这道题目是要找出所有可行的解,一般这种问题可以向动态规划,递归和回溯法的方向去考虑。这道题目的解法就是使用了回溯法,设定两个int open和close分别代表当前str中(和)的个数,如果open public class Solution { private void backtrack(List list, String str, int open, int close, int

2016-07-12 11:20:28 226

原创 LeetCode - 14. Longest Common Prefix

这道题目的解法非常值得借鉴,一开始的思路是先用str[0]开始,逐个增加pre,并且分别检查其他的string是否含有pre作为开头。但是这道题目是首先把pre设置为str[0],并且依次向后检测其他的string是否含有这个pre作为开头,如果没有的话那么就使用String的substring method将pre的长度减一,然后再进行检测。最差的情况下时间复杂度为O(S),其中S为所有stri

2016-07-11 13:46:02 363

原创 LeetCode - 3. Longest Substring Without Repeating Characters

这道题目的思想是使用一个HashSet来存储Longest Substring Without Repeating Characters,同时使用两个指针i,j分别指向HashSet的第一个元素将要添加的元素,如果j指向的当前将要添加的元素不存在于HashSet中,那么我们就将这个元素加入HashSet,同时更新max的值;如果j指向的当前元素已经在HashSet中,那么我们就删除i所指向的元素并

2016-07-10 20:28:24 162

原创 LeetCode - 2. Add Two Numbers

一开始的想法是先把两个数都从Linked List中解析出来,相加然后再将其转化为Linked List,但是这种解法非常麻烦,而且这三步完全可以同时进行。首先设置一个dummyNode作为sum表示的起点,然后从两个Linked List的开头逐个数字逐个数字地取出来,将其相加并除以10,记录得到的商和余数,将余数的值作为新节点的value new一个新的ListNode,并将其添加到dum

2016-07-10 18:50:16 247

原创 LeetCode - 49. Group Anagrams

这道题目的基本思想是使用一个Map>来存储grouped anagrams,对于数组中的每一个String,首先将其转化为char[],因为Java中String是不可改变的,然后对转化之后的char[]进行排序,再使用String.valueOf(char[])来得到它所对应的String value,这样所有的anagram都会有相同的String value。接下来检测Map中是否已经含有这

2016-07-10 12:56:23 300

原创 LeetCode - 242. Valid Anagram

这道题与cc 150 1.3类似,可以有多种解法,最为方便的一种就是排序,然后检查两个String[]是否相等。时间复杂度为O(nlogn),空间复杂度为O(n),代码如下:public boolean isAnagram(String s, String t) { if (s.length() != t.length()) { return false; }

2016-07-10 11:25:21 259

原创 LeetCode - 55. Jump Game

这道题是一个判断“能不能”的问题,所以想到可以使用动态规划来解决,DP的几个要素如下:state: f[i]表示能否跳到第i个位置function: f[i] = OR(f[j], j initialize: f[0] = truelanswer: f[n - 1]这种方法的时间复杂度为O(n ^ 2),空间复杂度为O(n),在LeetCode上没有通过,得到了TLE的结果,不

2016-07-10 11:01:52 448

原创 LeetCode - 337. House Robber III

这道题目具有Binary Tree的结构并且拥有最优子结构这一性质,也就是说如果我们想从当前的root抢劫到最多的钱,那么我们也希望在root的left和right子树上面抢到最多的钱。题目中已经给出了rob(root)这个函数,所以目前我们需要的就是分析出如何从最优的一些子问题上构造出当前根节点的最优解,也就是怎样从rob(root.left), rob(root.right)中得到rob(ro

2016-07-10 09:44:03 307

原创 LeetCode - 213. House Robber II

这道题目是House Robber的升级版,在这一题中,房子首尾相连,所以头部的房子和尾部的房子不能同时抢劫,这道题目只是比上道House Robber题目多了这一个限制条件,在上道题目中,第一个房子可以随意选择抢劫或者不抢劫,而这道题目里第一个房子是否抢劫受到最后一个房子是否被抢劫的限制。由于题目的大致结构还是一样的,所以我们洗完更能够利用上道题目的解法来处理这个题目,经过思考后我们可以发现,这

2016-07-10 09:22:18 357

原创 LeetCode - 112. Path Sum

遇到Binary Tree相关的问题,自然是要思考recursion和divide and conquer:对于一个root结点,如果它的左子树中有这样一条path,使得所有结点val的和等于sum - root.val;或者它的右子树中有这样一条path,使得所有结点val的和等于sum - root.val,那么就存在这样一条path,使得从root到leaf的所有结点的val和等于sum,基

2016-07-09 21:16:12 263

原创 LeetCode - 198. House Robber

每一个house都有rob和not rob两种状态,所以我们可以使用一个[n][2]的矩阵来记录每个房子被抢和不被抢的情况下所累计的钱的数量,这道动态规划问题的四要素如下:state: f[i][0], f[i][1]记录某个房子被抢或者不被抢的情况下所累积的钱的数量function: f[i][0] = max(f[i - 1][0], f[i - 1][1]),如果当前的房子不被抢,那

2016-07-09 20:40:39 404

原创 LeetCode - 70. Climbing Stairs

求问一共有多少种方式,而且题目中也比较明确地给出了递推关系,所以考虑使用动态规划,这道题属于Sequence DP,一般这种类型的动态规划问题考虑的四个要素如下:而对于这道题目:state: f[i]表示前i个位置,跳到第i个位置的方案总数function: f[i] = f[i - 1] + f[i - 2]initialize: f[0] = 1, f[1] = 1answ

2016-07-09 19:48:07 196

原创 LeetCode - 64. Minimum Path Sum

和上面的两道题目Unique Paths, Unique Paths II是一样的,都属于Matrix类型的Dynamic Programming问题,不同的是这道题目是要找到权重最小的路径,所以相应的一些分析也要变化一下:state: f[x][y]从起点走到x, y的最短路径function: f[x][y] = min(f[x - 1][y], f[x][y - 1]) + cost

2016-07-09 19:29:17 260

原创 LeetCode - 63. Unique Paths II

这道题目与上一个题目是一样的,只是在matrix中有些小格子里有障碍,无法通行。基本的思路与上道题目是一样的,只是在初始化和进行DP的时候都要先进行一下检查,检查当前的访问到的[i][j] == 1,如果true则说明有障碍,将当前的[i][j]设置为0,如果false则按照原来的方式进行。DP的几个要素如下:state: f[i][j]表示从左上角到当前的点有几种走法function:

2016-07-09 18:32:42 261

原创 LeetCode - 62. Unique Paths

这道题是一道典型的动态规划题目,在题目中出现以下情况的话经常要考虑使用动态规划的方法:而动态规划的话,通常会有以下几种类型:Matrix, Sequence, Two Sequences和Backpack。这道题目就是Matrix DP,而在Matrix DP中,有四个步骤需要考虑:state: f[x][y]表示从起点走到坐标x,y...function: 研究最后一步怎么走

2016-07-09 17:06:29 246

原创 LeetCode - 109. Convert Sorted List to Binary Search Tree

同样是构建平衡的BST,这道题目的思路与上一题是一样的,都是通过递归调用的方式逐步找到每一个子树的root,然后添加左子树和右子树。因为这里数字的载体由array变成了linked list,所以也变得更加复杂起来,最重要的就是在给出一个头节点和尾节点,找到mid结点的方法,这个可以使用fast/slow runnner来实现。时间复杂度为O(n),代码如下:/** * Definition

2016-07-07 21:26:45 279

原创 LeetCode - 108. Convert Sorted Array to Binary Search Tree

从一列已排序的数组中构造BST,如果题目中没有其他要求的话,那么这道题目基本是没办法写的,因为构造出的BST不止一种。注意到题目中有一个很小但是非常关键的条件,就是"height balanced BST",也就是说要root结点左子树和右子树的高度差距尽可能小,又根据BST的性质,如果对其中序遍历的话得到的序列一定是ascending的,所以可以直接在数组中(left + right) / 2的

2016-07-06 11:29:29 299

原创 LeetCode - 350. Intersection of Two Arrays II

这道题在349. Intersection of Two Arrays的基础上添加了允许重复这一条件,其实思路和上道题目都是一样的,只是将数据结构从不允许重复的Set换成了允许重复的ArrayList或允许对同一个元素重复计数的HashMap即可。时间复杂度为O(n),两种方法的代码如下:public class Solution{ public int[] intersect(int

2016-07-06 09:40:36 438

原创 LeetCode - 349. Intersection of Two Arrays

这个题目中既然提到了distinct,duplicate相关的问题,那么自然可以想到使用Set。首先使用一个Set记录nums1中的所有元素,因为是Set,所以这样就消除了nums1中的重复元素,接着使用另一个Set记录nums1和nums2的共有元素,对于nums2中的元素,如果第一个Set中含有这个元素,那么将这个元素加入到第二个Set中。同样地,由于Set不允许重复元素,这样同样又消去了重复

2016-07-06 09:12:57 268

原创 LeetCode - 345. Reverse Vowels of a String

和前面Reverse String的思想是一样的,同样是需要维护两个指针,一个在开头,一个在结尾,如果遇到元音字母就互相交换它们。注意这里判断原因字母的方法,使用了一个String vowel:  "aeiouAEIOU",如果vowel.indexOf(c) == -1,那么说明当前的这个字符不是元音字母。代码如下:public class Solution { public Str

2016-07-06 08:07:54 336

原创 LeetCode - 344. Reverse String

reverse string和reverse int[]的方法都是一样的,经典的方法就是使用两个指针,一个初始化为头部,另一个初始化为尾部,相互交换内容后加加减减指针。另外有一个cheat的方法就是使用Java中的StringBuilder类。两种方法的代码如下:// Method One: Cheating method using StringBuilderpublic class So

2016-07-05 22:38:57 209

原创 LeetCode - 19. Remove Nth Node From End of List

一个比较容易想到的方法就是使用two-pass,第一遍找到Linked List的长度,继而找到从前面看应该删除第几个Node。但是题目的要求是使用one-pass,那么就要使用two pointers了,首先让fast pointer跑到从前面看第n + 1个node的位置,然后同时移动(注意都是从dummyNode开始移动)slow和fast pointer,这时当fast为null的时候,s

2016-07-05 20:46:25 158

原创 LeetCode - 20. Valid Parentheses

这道题目一开始看错了,以为String中各种char都可能有,其实只可能有六种情况,那么只要分别处理这六种情况即可。另外处理类似于Palindrome问题的时候,一般都需要用到two pointer或者stack。代码如下:public class Solution { public boolean isValid(String s) { if(s == null ||

2016-07-05 20:15:46 242

原创 LeetCode - 230. Kth Smallest Element in a BST

这道题目需要利用BST的性质,就是如果对BST进行中序遍历的话,得到的序列的一定是sorted,所以一开始使用了一个ArrayList存储访问的元素,然后返回第k - 1个。但是这种方法不太好,更好的方法是利用k,在访问的过程中,每访问到一个结点就将k的值-1,当k == 0的时候,直接返回当前结点即可。时间复杂度为O(k),三种方式的代码如下:知识点:1. 注意利用BST inorder

2016-07-05 18:22:30 214

原创 LeetCode - 9. Palindrome Number

这道题目的思想是将x中每一位每一位取出来反向乘以10相加,与原来的数字相比较,但是这样可能会造成溢出,所以我们取x中的后n - 1位,然后比较后n - 1位反向组成的数字与x / 10是否相等 && x中的最后一位和第一位是否相等,代码如下:public class Solution { public boolean isPalindrome(int x) {

2016-07-05 11:40:47 190

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

Binary Tree的问题,首先要考虑使用递归的思想:如果当前的结点为空或为目标结点之一,那么就直接返回当前结点,接下来递归地在左右子树中寻找目标结点,如果两个目标结点分别在root的两侧,那么root就是它们的lowest common ancestor;如果left为空,那么说明两个目标结点都在right子树中,返回right;反之则返回left。代码如下:/** * Definiti

2016-07-05 10:50:01 296

空空如也

空空如也

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

TA关注的人

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