1 | Two Sum | 求数组中等于target的两个数的下标 | 数组 | O(n*n) | O(n),用HashMap存已遍历部分 |
2 | Add Two Numbers | 两数相加,数用链表表示,低位在头,高位在尾 | 链表 | 当l1、l2不为空或tmp不为0时,依次相加,得到tmp,tmp%10即当前位,tmp/10为进位 | |
3 | Longest Substring Without Repeating Characters | 求字符串中不包含重复字符的最长子串 | 字符串 | 遍历字符串,并将当前字符和其位置放在map里,如果map里有该字符,则从那个字符的右侧第一个开始到当前字符则是最长的字符串 | |
4 | Median of Two Sorted Arrays | 两个有序数组的中间值 | 数组 | 数组的遍历,先写找kth的方法 | |
5 | Longest Palindromic Substring | 求字符串中最长的回文串子串 | 字符串 | 从当前字符向两边扩展,或者从当前字符和当前字符的下一个字符向两边扩展 | |
6 | ZigZag Conversion | 求字符串的ZigZag转换结果(理解ZigZag,发现规律) | 字符串 | numRows个StringBuffer,遍历原字符串,用index标记numRows行到numRows就转方向,一一添加到第index个StringBuffer | |
7 | Reverse Integer | 反转整型数,如果反转得到的整型数超出范围,则返回0 | 使用StringBuffer来追加每一位数字,最后使用Integer.parseInt()来转换成整型数,如果转换中出现异常,则返回0,以此解决溢出问题 | 哇,太机智。如果(新结果-tail)/10不等于原结果,则是溢出应返回0,否则更新结果。一般做法是声明一个long类型的res,如果res大于最大值或小于最小值,则返回0. | |
8 | String to Integer (atoi) | 将字符串转化为整型数 | 字符串 | 特殊用例太多,注意各种特殊情况,判断正负,判断溢出,判断无效 | 用ascii码直接减,不必写一一转化的函数,Character有函数可以判断是否数字字符,或者c-'0'得到的结果大于9或小于0,也可以判断是否数字字符 |
9 | Palindrome Number | 判断整数是否为回文数 | 用reverse得到反转数,判断反转数与原数是否相同,负数都不是回文数 | 机智解答:不除到个位上,这样就不会有溢出了。 | |
10 | Regular Expression Matching | 正则表达式匹配 | |||
11 | Container With Most Water | 装水问题,(i,ai)之间组成最大容积的水桶 | 暴力解会超时,所以思考如何剪枝,发现规律,从两边向中间移动,每次都是高度低的移 | ||
12 | Integer to Roman | 将整数转换成罗马数字 | 开辟了一个字符串数组,对应存储了1-9,10-90,100-900,1000-3000的罗马数字形式,依次取各位,转换 | 存储1000到1独特表示的数字,遍历这个数组,如果数字大于当前位置的数,则减并追加字符串 | |
13 | Roman to Integer | 将罗马数字转换成整数 | 同上,这次是如果字符串s与当前字符串匹配上,则加并取子串。 | ||
14 | Longest Common Prefix | 最长公共子串 | 先找到最短的串长,遍历,第i个字符是否都一样,一旦有一个不一样,结束遍历返回结果 | 将字符串数组排序,然后只需要比较首字符串和尾字符串即可,效率差不多 | |
15 | 3Sum | 三数之和为0 | 排序后,以第i个为基准,从i+1和最后一个向中间逼近,找到其和为零的三个数,这样会超时,需要剪枝重复情况,如何当前元素等于上一个元素,就跳过当前元素,需要剪枝i,j,k | ||
16 | 3Sum Closest | 三数之和最接近target | 排序,遍历,如果sum大于target,则k--,否则j++,更新结果 | ||
17 | Letter Combinations of a Phone Number | 将手机数字转换成字母组合 | 遍历做的 | FIFO,用LinkedList来模拟队列即可。 | 递归做一遍 |
18 | 4Sum | 四数之和 | 计算两两之和,然后计算两两之和 | ||
19 | Remove Nth Node From End of List | 移除倒数第n个结点 | 遍历一遍得到结点总数,计数移除 | 设置两个指针,一个快指针,先走到正数第n+1个结点处,然后快慢指针一起走,直到快指针走到了末尾,这是慢指针指向了要删除的结点的前节点,删除慢指针的next节点即可。 | |
20 | Valid Parentheses | 栈不为空时,与栈顶元素匹配,未匹配成功,压入栈,否则弹出栈顶元素。直到所有符号遍历完,如果栈不为空,则false |
|||
21 | Merge Two Sorted Lists | 合并两个有序链表 | 依次添加就可以 | 效率高一些的方法就是递归 | |
22 | Generate Parentheses | 给定一个数n,生成n对有效括号序列 | 采用递归,从左n,右n开始,如果左大于0,则加入左括号,如果右大于0,并且左小于右,则加入右括号,当左和右均为0,则得到一个有效结果 | ||
23 | Merge k Sorted Lists | 合并K个有序链表 | 依次两两合并会超时,解决方法是使用二分法来两两合并。 | 使用一个升序的优先队列,将k个链表的一个结点依次放到队列中,队列弹出结点,弹出结点有next结点则next结点加入队列。直到队列为空。 | |
24 | Swap Nodes in Pairs | 两两交换1-2-3-4=》2-1-4-3 | 用了几个指针来标记各位置,遍历一遍交换完毕 | 递归解决 | |
25 | Reverse Nodes in k-Group | ||||
26 | Remove Duplicates from Sorted Array | 移除重复元素,返回新长度 | 遍历拷贝,效率不好 | j记录当前个数,如果a[j]!=a[i],则将第++j个位置赋值为a[i] | |
27 | Remove Element | 移除等于特定值的元素,返回新长度 | 将等于特定值的元素赋值为Integer的最大值,排序 | 对于每一个不等于特定值的元素都重新赋值给新位置 | |
28 | Implement strStr() | 子串第一次出现的位置 | 如果haystack长度小于needle,则返回-1;如果haystack与needle相同,则返回0;遍历haystack,看某个位置起的子串是否与needle相同。 | ||
29 | Divide Two Integers | 除法(不用乘除模) | 普通减法超时 | 考虑符号问题,加减法做除法,必须是正数。 考虑边界问题。 除法考虑递归处理 |
|
30 | Substring with Concatenation of All Words | ||||
31 | Next Permutation | 下一个全排列 | 总结规律,降序序列的前一个元素与降序序列倒数第一个比该元素大的元素交换,然后将倒数第一个元素后的元素倒置 | ||
32 | Longest Valid Parentheses | ||||
33 | Search in Rotated Sorted Array | 二分查找,但是是旋转型有序数组 | |||
34 | Search for a Range | 在有序数组中找到某个数的范围 | 使用二分法,先找到一个等于某数的位置,然后左右扩展,得到结果 | 递归做法效率好像更好 | |
35 | Search Insert Position | 在有序数组找到某数的插入位置 | 二分查找,直到start>end,结束循环,返回start | ||
36 | Valid Sudoku | 有效数独的验证 | 横向验证,纵向验证,3*3验证,使用set | ||
37 | Sudoku Solver | ||||
38 | Count and Say | 题意难理解,计数并复述。对上一个串计数,加入第3个,因为第2个是11.所以第3个计数应该是21,两个1。第4个就是一个2,1个1,即1211 | 遍历 | 遇到字符串拼接优先用StringBuilder,而不是直接+,提高效率 | |
39 | Combination Sum | 找到和为target的组合 | 回溯,dfs,递归 | ||
40 | Combination Sum II | 与上一题类似,但不重复使用某元素 | 在上一个题目的基础上,判断元素是否已存在组合中 | ||
41 | First Missing Positive | ||||
42 | Trapping Rain Water | ||||
43 | Multiply Strings | 计算两个字符串形式的数的乘积 | 用二维数组保存中间状态,最后的结果是一行加一列 | 改进用一维数组存储每位的计算结果 | |
44 | Wildcard Matching | ||||
45 | Jump Game II | ||||
46 | Permutations | 给定的数组中无重复值,递归 | 用一个一维数组标记元素是否访问过,对于没有访问过的元素才加入排列中 | ||
47 | Permutations II | 给定的数组中有重复值,递归加剪枝 | 将重复数值的递归过程省略(也就是说遇到之前递归调用过的数值,我们就跳过) | 对于重复的元素循环时跳过递归函数的调用,只对第一个未被使用的进行递归,我们那么这一次结果会出现在第一个的递归函数结果中,而后面重复的会被略过。如果第一个重复元素前面的元素还没在当前结果中,那么我们不需要进行递归。 首先我们要对元素集合排序,从而让重复元素相邻,接下来就是一行代码对于重复元素和前面元素使用情况的判断即可。 |
|
48 | Rotate Image | n*n的矩阵顺时针旋转90度 | 申请一个n*n的空间 | 一次对角线对称交换,一次中线对称交换 | |
49 | Group Anagrams | 用List存超时,确实用到了转换为char数组排序,得到的字符串放到list会超时,应该用Map,最后将Map的values集合给List | |||
50 | Pow(x, n) | 求解x的n次方(注意此处n可为负数啊) | 超时就要想到用递归,直接用递归做法,不要总是暴力求解 | 先求pow(x,n/2)的值,如果n%2==0,则直接返回值*值;否则判断n是大于0还是小于0,如果大于0则值*值*x,否则值*值/x. | |
51 | N-Queens | ||||
52 | N-Queens II | ||||
53 | Maximum Subarray | 求最大子串和经典一维DP问题 | max(A[i],Start[i+1],All[i+1]) | ||
54 | Spiral Matrix | 输出螺旋结果 | 分析题目,发现j++,i++,j--,i--循环来做,然后要寻找终止条件,我的想法是计数加是否访问来判断是否结束 | 机智解答中仅用四个变量来对此进行控制,少了很多空间 | |
55 | Jump Game | 一维贪心 | 好好分析题目,不难。 | ||
56 | Merge Intervals | 合并 | 先排序,后合并 | Arrays.sort的效率比List的sort的效率高太多了 | |
57 | Insert Interval | ||||
58 | Length of Last Word | 字符串中的最后一个单词的长度 | 倒着遍历,找第一个空格,找到了就返回i++, | ||
59 | Spiral Matrix II | ||||
60 | Permutation Sequence | 求n个数的全排列中的第k个 | 假设n=4,则有(1,2,3,4),假设k= 14; 每个数字在首位出现的次数都是3!=6,那么我们用(14-1)/3!=2,可以得到首位为3。接下来计算第2位,1/2!=0,也就是1,被取出;第3位1/1=1,也就是4,被取出;第4位,则是2 |
a1=(k-1)/(n-1)!+1 | |
61 | Rotate List | 先求全长,然后移动指针到倒数第k%n个位置 | 如果k大于链表长度,则取k%len;否则fast先到达第k个位置,然后fast和slow一起走,知道fast走到末尾,slow走到倒数第k个位置,开始旋转List. | ||
62 | Unique Paths | 求左上角到右下角的独立路径多少个 | 数学方法,C(m-1,(m+n-2)) | DP做法,转移方程为dp[i][j]=dp[i-1][j]+dp[i][j-1] | 一维数组DP实现,方程:dp[i]+=dp[i-1]; |
63 | Unique Paths II | 上题的进阶版,加了路障 | 要添加一些判断:Start和End位置有路障,直接0;对于第0行和第0列的处理,如果有路障则当前元素为0,否则为上一个元素的值;然后从1,1开始遍历,结果为dp[m-1][n-1] | 还有一维数组实现,方程是一样的 | 与二维处理类似,只不过把一个列的处理放到大循环里面。 |
64 | Minimum Path Sum | 经典DP问题 | 转移方程与62类似 | ||
65 | Valid Number | ||||
66 | Plus One | 普通做法效率低一些 | 机智做法呢,就是判断找到第一个位小于9的,之前大于9的都为0,小于就不用纠结进位问题,直接+1,返回结果,如果进位导致结果数组长度比原数组大,则创建一个新数组,直接置最大位置为1,其他为0,这种情况只有在各位全9才出现 | ||
67 | Add Binary | 二进制加法,11+1=100 | 注意是2进制,所以模和除都是2 | 机智做法来源于异或操作。 | |
68 | Text Justification | ||||
69 | Sqrt(x) | 二分搜索,构造一个end=x+1,注意类型必须是long,以免越界 | |||
70 | Climbing Stairs | 爬台阶 | 规律即斐波那契数列,递归求解会超时,所以需要一个数组来记录已经求过的斐波那契数 | ||
71 | Simplify Path | 简化路径 | 用栈,如果是..,则弹栈,如果不是".."或"."或"",则压栈 | ||
72 | Edit Distance | ||||
73 | Set Matrix Zeroes | 普通做法用Set存储符合条件的i和j | 用matrix本身的第一行和第一列来标记当前行或列是否清0,对第一行和第一列元素,使用两个flag标记处理 | ||
74 | Search a 2D Matrix | 二分法 | 还可以直接看当前行,小于就换行,大于就在当前行移动寻找 | ||
75 | Sort Colors | 对只有012三个数的数组排序 | 时间复杂度O(n)。给出两个标记p0=0和p2=n-1,分别记录当前0的位置和2的位置,如果当前元素等于2,则交换p2和i位置的元素,i--(之所以要i--,是因为交换过来的值有可能是0或1啊), | 还有计数的方法,一次遍历得到0、1和2的个数,再遍历一遍赋值; | |
76 | Minimum Window Substring | ||||
77 | Combinations | 求组合,与求排列类似 | 都是递归调用,注意如何写调用过程,以及什么是退出条件 | ||
78 | Subsets | 求子集 | 位操作解法,一个长度为len的数组,其子集的个数为2^n,每一个数代表一个子集,每一位代表数组当前下标元素在不在集合内 | 递归调用 | |
79 | Word Search | 在2D的矩阵中是否存在字符串匹配的字符串 | 递归解决,递归条件就是长度等于待匹配的字符串 注意各种边界,是否访问过等 上下左右四个字符是否与字符串匹配 |
不需额外空间存储,巧妙地运用了异或操作,对于访问过的字符,通过异或来表示它被访问过,再异或恢复原值 | |
80 | Remove Duplicates from Sorted Array II | ||||
81 | Search in Rotated Sorted Array II | ||||
82 | Remove Duplicates from Sorted List II | ||||
83 | Remove Duplicates from Sorted List | 遍历 | |||
84 | Largest Rectangle in Histogram | ||||
85 | Maximal Rectangle | ||||
86 | Partition List | 分割List,使得前半部分为小于x的,后半部分为大于等于x的 | 设置两个头,一个记录小于x的,一个记录大于等于x的,然后遍历判断。最后一定记得把more.next设为null,否则链表会成环,导致死循环 | ||
87 | Scramble String | ||||
88 | Merge Sorted Array | 合并两个有序数组 | 最好是从后面开始复制,不用移动太多元素 | ||
89 | Gray Code | 格雷码 | 巧妙地用异或 | ||
90 | Subsets II | 带重复数字的数组 | 需要在加入结果时,判断是否已存在 | 在移除之后就判断是不是重复数字,如果是,则跳过就可以了 | |
91 | Decode Ways | 类似于爬台阶的DP | 一维数组来存,需要考虑当前位是否为0,为0,则找后一位,否则找后两位。 | ||
138 | Copy List with Random Pointer | 深度拷贝链表 | 用Map的键存储原来的链表,值存拷贝结果,把所有的节点拷贝过去之后,接下来,就是编译一般,根据键取值赋值 | 时间复杂度O(n) | //第一遍扫描:对每个结点进行复制,把复制出来的新结点插在原结点之后 //第二遍扫描:根据原结点的random,给新结点的random赋值 //第三遍扫描:把新结点从原链表中拆分出来 |