喜刷刷1

Lakukan tugas rumah & ujian kamu dengan baik sekarang menggunakan Quizwiz!

[LeetCode#96] Unique Binary Search Trees 独一无二的二叉搜索树 Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example, Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3

Catalan Number卡塔兰数 DP dp[0] = 1 dp [1] = dp[0]*dp[0] = 1 dp[2] = dp[0]*dp[1] + dp[1]*dp[0] = 2 dp[3] = dp[0]*dp[2] + dp[1]*dp[1] + dp[2]*dp[0] = 5 dp[0] = 1; dp[1] = 1; for (int i = 2; i <= n; ++i) { for (int j = 0; j < i; ++j) { dp[i] += dp[j] * dp[i - j - 1]; } }

[LeetCode#41] First Missing Positive 首个缺失的正数 Given an unsorted integer array, find the first missing positive integer. For example, Given [1,2,0] return 3, and [3,4,-1,1] return 2. Your algorithm should run in O(n) time and uses constant space.

#1 Not constant space HashMap, scan two times #2 O(0) space 既然不能建立新的数组,那么我们只能覆盖原有数组,我们的思路是把1放在数组第一个位置A[0],2放在第二个位置A[1],即需要把A[i]放在A[A[i] - 1]上,那么我们遍历整个数组,如果A[i] != i + 1, 而A[i]为整数且不大于n,另外A[i]不等于A[A[i] - 1]的话,我们将两者位置调换,如果不满足上述条件直接跳过,最后我们再遍历一遍数组,如果对应位置上的数不正确则返回正确的数 [Mine]#2排序过程中剔除肯定错误的数(A[i]>n || A[i]<0),将正确的数放在正确的位置,然后scan again,找第一个缺失数 [Mine]#2类似于基数排序,自然数都可以考虑这样算法。

[LeetCode#73] Set Matrix Zeroes 矩阵赋零 Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. click to show follow up. Follow up: Did you use extra space? A straight forward solution using O(mn) space is probably a bad idea. A simple improvement uses O(m + n) space, but still not the best solution. Could you devise a constant space solution?

- 先扫描第一行第一列,如果有0,则将各自的flag设置为true - 然后扫描除去第一行第一列的整个数组,如果有0,则将对应的第一行和第一列的数字赋0 - 再次遍历除去第一行第一列的整个数组,如果对应的第一行和第一列的数字有一个为0,则将当前值赋0 - 最后根据第一行第一列的flag来更新第一行第一列

[LeetCode#87] Scramble String 爬行字符串 Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively. Below is one possible representation of s1 = "great": great / \ gr eat / \ / \ g r e at / \ a t To scramble the string, we may choose any non-leaf node and swap its two children. For example, if we choose the node "gr" and swap its two children, it produces a scrambled string"rgeat". rgeat / \ rg eat / \ / \ r g e at / \ a t We say that "rgeat" is a scrambled string of "great". Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string"rgtae". rgtae / \ rg tae / \ / \ r g ta e / \ t a We say that "rgtae" is a scrambled string of "great". Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.

#1 Recursion 简单的说,就是s1和s2是scramble的话,那么必然存在一个在s1上的长度l1,将s1分成s11和s12两段,同样有s21和s22.那么要么s11和s21是scramble的并且s12和s22是scramble的;要么s11和s22是scramble的并且s12和s21是scramble的。 #2 DP ????? 三维动态规划的题目,我们提出维护量res[i][j][n],其中i是s1的起始字符,j是s2的起始字符,而n是当前的字符串长度,res[i][j][len]表示的是以i和j分别为s1和s2起点的长度为len的字符串是不是互为scramble。 递推式是res[i][j][len] = || (res[i][j][k]&&res[i+k][j+k][len-k] || res[i][j+len-k][k]&&res[i+k][j][len-k]) 对于所有1<=k<len,也就是对于所有len-1种劈法的结果求或运算。因为信息都是计算过的,对于每种劈法只需要常量操作即可完成,因此求解递推式是需要O(len)(因为len-1种劈法)。 如此总时间复杂度因为是三维动态规划,需要三层循环,加上每一步需要线行时间求解递推式,所以是O(n^4)。虽然已经比较高了,但是至少不是指数量级的,动态规划还是有很大优势的,空间复杂度是O(n^3)。 dp[i][j][1] = s1[i] == s2[j]; for (int len = 2; len <= n; ++len) { for (int i = 0; i <= n - len; ++i) { for (int j = 0; j <= n - len; ++j) { for (int k = 1; k < len; ++k) { if ( (dp[i][j][k] && dp[i + k][j + k][len - k]) || (dp[i + k][j][len - k] && dp[i][j + len - k][k])) { dp[i][j][len] = true; } } } } } return dp[0][0][n]; [Mine] 一个字符串单向递推,用一维DP; 一个字符串内部结构扩散递推(比如:回文)用二维DP; 两个字符串单向递推,用二维DP; 两个字符串内部结构扩散递推(this),用三维DP

[LeetCode#47] Permutations II 全排列之二 Given a collection of numbers that might contain duplicates, return all possible unique permutations. For example, [1,1,2] have the following unique permutations: [1,1,2], [1,2,1], and [2,1,1].

#1 sort then 在递归函数中要判断前面一个数和当前的数是否相等

[LeetCode#42] Trapping Rain Water 收集雨水 Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

#1 一个一维的dp数组,这个DP算法需要遍历两遍数组,第一遍遍历dp[i]中存入i位置左边的最大值,然后开始第二遍遍历数组,第二次遍历时找右边最大值,然后和左边最大值比较取其中的较小值,然后跟当前值A[i]相比,如果大于当前值,则将差值存入结果 #2 只需要遍历一次即可的解法,这个算法需要left和right两个指针分别指向数组的首尾位置,从两边向中间扫描,在当前两指针确定的范围内,先比较两头找出较小值,如果较小值是left指向的值,则从左向右扫描,如果较小值是right指向的值,则从右向左扫描,若遇到的值比当较小值小,则将差值存入结果,如遇到的值大,则重新确定新的窗口范围,以此类推直至left和right指针重合 [Mine]由#1知道,我们关心每个位置左右能看到的最高柱的较小者。#2就是不断在左右较小柱向中间掘进,掘进过程中发现的洼地都能确定其左右高柱较小者 [Mine]我们的目标是找到碗型,所以要找两沿高,中间比两沿低的地方

[LeetCode#78] Subsets 子集合 Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,3], a solution is: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]

#1 一位一位的网上叠加,比如对于题目中给的例子[1,2,3]来说,最开始是空集,那么我们现在要处理1,就在空集上加1,为[1],现在我们有两个自己[]和[1],下面我们来处理2,我们在之前的子集基础上,每个都加个2,可以分别得到[2],[1, 2],那么现在所有的子集合为[], [1], [2], [1, 2],同理处理3的情况可得[3], [1, 3], [2, 3], [1, 2, 3], 再加上之前的子集就是所有的子集合了 #2 void getSubsets(vector<int> &S, int pos, vector<int> &out, vector<vector<int> > &res) { res.push_back(out); for (int i = pos; i < S.size(); ++i) { out.push_back(S[i]); getSubsets(S, i + 1, out, res); out.pop_back(); } } #3 把数组中所有的数分配一个状态,true表示这个数在子集中出现,false表示在子集中不出现,那么对于一个长度为n的数组,每个数字都有出现与不出现两种情况,所以共有2n中情况 每个子集的序号的二进制表示,把是1的位对应原数组中的数字取出来就是一个子集

[LeetCode#98] Validate Binary Search Tree 验证二叉搜索树 Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys greater than the node's key. Both the left and right subtrees must also be binary search trees.

#1 最简单的一种,就是利用其本身性质来做,初始化时带入系统最大值和最小值,在递归过程中换成它们自己的节点值,用long代替int就是为了包括int的边界条件 #2 中序遍历:recursion, Iterative, Morris

[LeetCode#48] Rotate Image 旋转图像 You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Follow up: Could you do this in-place?

#1 直接的方法,对于当前位置,计算旋转后的新位置,然后再计算下一个新位置,第四个位置又变成当前位置了,所以这个方法每次循环换四个数字 for (int i = 0; i < n / 2; ++i) { for (int j = i; j < n - 1 - i; ++j) { int tmp = matrix[i][j]; matrix[i][j] = matrix[n - 1 - j][i]; matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j]; matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i]; matrix[j][n - 1 - i] = tmp; } } #2 还有一种解法,首先以从对角线为轴翻转,然后再以x轴中线上下翻转即可得到结果 for (int i = 0; i < n - 1; ++i) { for (int j = 0; j < n - i; ++j) { swap(matrix[i][j], matrix[n - 1- j][n - 1 - i]); } } for (int i = 0; i < n / 2; ++i) { for (int j = 0; j < n; ++j) { swap(matrix[i][j], matrix[n - 1 - i][j]); } } #3 首先对原数组取其转置矩阵,然后把每行的数字翻转可得到结果 [Mine]确定循环边界(中心向外90度角三角区域swap,还是对角线swap),找目的左边和原坐标关系(原x计算目的y)

[LeetCode#76] Minimum Window Substring 最小窗口子串 Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n). For example, S = "ADOBECODEBANC" T = "ABC" Minimum window is "BANC". Note: If there is no such window in S that covers all characters in T, return the emtpy string "". If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

#1 考虑哈希表,其中key是T中的字符,value是该字符出现的次数。 - 我们最开始先扫描一遍T,把对应的字符及其出现的次数存到哈希表中。[Mine]存量 - 然后开始遍历S,遇到T中的字符,就把对应的哈希表中的value减一,直到包含了T中的所有的字符,纪录一个字串并更新最小字串值。 [Mine]所有存量消耗完,即哈希表中value没有大于0的 - 将子窗口的左边界向右移,略掉不在T中的字符,如果某个在T中的字符出现的次数大于哈希表中的value,则也可以跳过该字符 [Mine]遇到T中字符,相应哈希表中Value+1,一旦出现正值,开始移动右边界。 #2 也可以不用哈希表,直接用个int的数组来代替,因为ASCII只有256个字符,所以用两个大小为256的int数组即可代替哈希表

[LeetCode#4] Median of Two Sorted Arrays 两个有序数组的中位数 There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

#1 递归:(先判断总长度奇偶) findKth(vector<int> &nums1, int i, vector<int> &nums2, int j, int k) [Mine]整体上findKth。递归时,排除一定可以排除的范围,缩小搜索范围和依据新范围调整目标定义。每次分K/2在一个array(不超边界),剩余部分在另一个array上,这样直到正确的Kth,或一个array走到头,另一个array直接算出Kth #2 二分查找 我们在array中间cut一下,L是cut左面数字,R是cut右面数字,如果array是奇数,那么cut在同一个数字上,L=R,如果是偶数,cut在两个数字之间。 Median = (L + R)/2 = (A[(N-1)/2] + A[N/2])/2 [Mine]即cut在(0~2*N)上取值,为Median取了一半,为N;L为cut中的N-1,为原坐标中的(N-1)/2;R为cut中的N,为原坐标中的N/2 在两个array时,我们要找到在两个array上分别的两个cut,得到L1,R1,L2,R2,类似单一array上的定义,两个array最终中位数的地方一定是,L1,L2左面的数的个数和等于R1,R2右面的,并且所有L1,L2左面的数都小于R1,R2右面的数。最终的中位数将为 (max(L1,L2) + min(R1, R2)) / 2 先估算一个在短array1上的cut(取值范围0~2*N1),C1=N1(2*N1的一半),那么另外一个cut一定是另一个array2的C2 = N2+N1-C1(2*N1+2*N2的一半是N1+N2,这应该等于C1+C2) if L1 > R2, C1左面的数字大于C2右面的数字,我们需要C1向左移动(经过N1+N2-C1计算后,C2就会向右移动) If L2 > R1,C1右面的数字小于C2左面的数字,我们需要C1右移。 有C1左右移的判断方法了,就可以在array1(0~2*N1的cut范围)上二分查找合适的cut [Mine] (中位数,去奇偶判断的方法) 1. 统一了奇偶判断,通过 L1 = A1[(C1-1)/2]; R1 = A1[C1/2]; ( 0<=C1<=2*N1, L1,R1可以扫到A1任何CUT位置) L2 = A2[(C2-1)/2]; R2 = A2[C2/2]; ( 0<=C2<=2*N2,L2,R2可以扫到A2任何CUT位置) 来保证任何Cut都在(0~2N)上有坐标,无论cut在两数之间或一个数上 2. 2 array,一定是两个cut,并且一个确定了,另外一个就可以算出来。在短array上任何一个位置都可能是最终cut,但长array就不能保证。所以从短array上扫描 3. 找到左右移动的判断方法,就可以在短array上二分查找正确的cut(0~2N上二分找合适的cut) https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-4-median-of-two-sorted-arrays/ K = (n1+n2+1)/2 m1 + m2 = K array A and B, if combine, array C C[k-1] = max(A[m1-1], B[m2-1]); C[k] = min(A[m1], B[m2]) ret = C[k-1] if odd; (C[k-1]+C[k])*0.5 if even 在最短array上二分找cut点,确定m1,这样就能确定m2, C[k-1] and C[k]

[LeetCode#49] Group Anagrams 群组错位词 Given an array of strings, group anagrams together. For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], Return: [ ["ate", "eat","tea"], ["nat","tan"], ["bat"] ] Note: All inputs will be in lower-case.

#1 错位词重新排序后都会得到相同的字符串 #2 用一个大小为26的int数组来统计每个单词中字符出现的次数,然后将int数组转为一个唯一的字符串,跟字符串数组进行映射

[LeetCode#23] Merge k Sorted Lists 合并k个有序链表 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

#1不停的对半划分,比如k个链表先划分为合并两个k/2个链表的任务,再不停的往下划分,直到划分成只有一个或两个链表的任务,两两开始合并 #2 最小堆

[LeetCode#61] Rotate List 旋转链表 Given a list, rotate the list to the right by k places, where k is non-negative. For example: Given 1->2->3->4->5->NULL and k = 2, return 4->5->1->2->3->NULL.

#1快慢指针 #2先遍历整个链表获得链表长度n,然后此时把链表头和尾链接起来,在往后走n - k % n个节点就到达新链表的头结点前一个点,这时断开链表即可

[LeetCode#74] Search a 2D Matrix 搜索一个二维矩阵 Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted from left to right. The first integer of each row is greater than the last integer of the previous row. For example, Consider the following matrix: [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] Given target = 3, return true.

#1我们可以在第一列上先用一次二分查找法找到目标值所在的行的位置,然后在该行上再用一次二分查找法来找是否存在目标值 #2 按S型遍历该二维数组,可以得到一个有序的一维数组。 原一维数组中下标为i的元素将出现在二维数组中的[i/n][i%n]的位置

[LeetCode#30] Substring with Concatenation of All Words 串联所有单词的子串 You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters. For example, given: s: "barfoothefoobarman" words: ["foo", "bar"] You should return the indices: [0,9]. (order does not matter).

2 hashmap<string, int>

[LeetCode#57] Insert Interval 插入区间 Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times. Example 1: Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. Example 2: Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10].

- 对区间集中每个区间进行遍历 - 如果新区间的末尾小于当前区间的开头,则跳出循环 - 如果新区间的开头大于当前区间的末尾,不作处理 - 如果新区间和当前区间有重叠,则更新新区间的开头为两者最小值,新区间的末尾为两者最大值,重叠数加一 - 指针移向下一个区间 - 如果重叠数大于0,则删除掉所有的重叠区间 - 插入新区间到对应的位置 [Mine]记录重叠区间的开始index,overlap区间个数,新重叠区间的新最小值和最大值

[LeetCode#68] Text Justification 文本左右对齐 Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly Lcharacters. Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. For the last line of text, it should be left justified and no extra space is inserted between words. For example, words: ["This", "is", "an", "example", "of", "text", "justification."] L: 16. Return the formatted lines as: [ "This is an", "example of text", "justification. " ] Note: Each word is guaranteed not to exceed L in length. click to show corner cases. Corner Cases: A line other than the last line might contain only one word. What should you do in this case? In this case, that line should be left-justified.

1.确定每一行能放下的单词数,这个不难,就是比较n个单词的长度和加上n - 1个空格的长度跟给定的长度L来比较即可,找到了一行能放下的单词个数,然后计算出这一行存在的空格的个数,是用给定的长度L减去这一行所有单词的长度和 2.要在每个单词后面插入这些空格, 最后一行的处理方法和其他行之间略有不同 3. 如果一行有三个单词,这时候中间有两个空,如果空格数不是2的倍数,那么左边的空间里要比右边的空间里多加入一个空格,那么我们只需要用总的空格数除以空间个数,能除尽最好,说明能平均分配,除不尽的话就多加个空格放在左边的空间里,以此类推

[LeetCode#12] Integer to Roman 整数转化成罗马数字 Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.

100 - C 200 - CC 300 - CCC 400 - CD 500 - D 600 - DC 700 - DCC 800 - DCCC 900 - CM 由于限制了输入数字范围这一特殊性,故而还有一种利用贪婪算法的解法 vector<int> val{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; vector<string> str{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};

[LeetCode#60] Permutation Sequence 序列排序 The set [1,2,3,...,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3): "123" "132" "213" "231" "312" "321" Given n and k, return the kth permutation sequence. Note: Given n will be between 1 and 9 inclusive.

????

[LeetCode#94] Binary Tree Inorder Traversal 二叉树的中序遍历 Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 \ 2 / 3 return [1,3,2]. Note: Recursive solution is trivial, could you do it iteratively?

?????? Recursion/iterative/Morris

[LeetCode#64] Minimum Path Sum 最小路径和 Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time.

DP dp[i][j]表示当前位置的最小路径 dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1]);

[LeetCode#2] Add Two Numbers 两个数字相加 You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8

Attention to carry

[LeetCode#97] Interleaving String 交织相错的字符串 Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example, Given: s1 = "aabcc", s2 = "dbbca", When s3 = "aadbbcbcac", return true. When s3 = "aadbbbaccc", return false.

DP 当s1和s2是空串的时候,s3必然是空串,则返回true。所以直接给dp[0][0]赋值true,然后若s1和s2其中的一个为空串的话,那么另一个肯定和s3的长度相等,则按位比较,若相同且上一个位置为True,赋True,其余情况都赋False,这样的二维数组dp的边缘就初始化好了。 在任意非边缘位置dp[i][j]时,从它的左边或上边更新过来 dp[i][j] = (dp[i - 1][j] && s1[i - 1] == s3[i - 1 + j]) || (dp[i][j - 1] && s2[j - 1] == s3[j - 1 + i]); 其中dp[i][j] 表示的是 s2 的前 i 个字符和 s1 的前 j 个字符是否匹配 s3 的前 i+j 个字符 [Mine]dp[i][j]是s1[0...i-1]和s2[0...j-1]是否匹配s3[0..i+j-1],所以和s1[i], s2[j]没有关系。 当判断dp[i][j]时,要判断s3[i+j-1]是来自s1[i-1],还是来自s2[j-1],其中之一。

[LeetCode#72] Edit Distance 编辑距离 Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.) You have the following 3 operations permitted on a word: a) Insert a character b) Delete a character c) Replace a character

DP dp[i][j]表示从word1的前i个字符转换到word2的前j个字符所需要的步骤 第一行和第一列对应的总有一个字符串是空串,于是转换步骤完全是另一个字符串的长度 当word1[i] == word2[j]时,dp[i][j] = dp[i - 1][j - 1],其他情况时,dp[i][j]是其左,左上,上的三个值中的最小值加1 if word1[i - 1] == word2[j - 1] dp[i][j] = dp[i - 1][j - 1] else dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1

[LeetCode#70] Climbing Stairs 爬梯子问题 You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

DP dp[n] = dp[n-1] + dp[n-2] 只用两个整型变量a和b来存储过程值,首先将a+b的值赋给b,然后a赋值为原来的b,所以应该赋值为b-a即可。这样就模拟了上面累加的过程,而不用存储所有的值 int a = 1, b = 1; while (n-- > 0) { b += a; a = b - a; } return a;

[LeetCode#62] Unique Paths 不同的路径 A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). How many possible unique paths are there? Above is a 3 x 7 grid. How many possible unique paths are there? Note: m and n will be at most 100.

DP p[i][j]表示到当前位置不同的走法的个数,然后可以得到递推式为: dp[i][j] = dp[i - 1][j] + dp[i][j - 1], 这里为了节省空间,我们使用一维数组dp,一行一行的刷新也可以 for (int i = 1; i < m; ++i) { for (int j = 1; j < n; ++j) { dp[j] += dp[j - 1]; } }

[LeetCode#45] Jump Game II 跳跃游戏之二 Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Your goal is to reach the last index in the minimum number of jumps. For example: Given array A = [2,3,1,1,4] The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

DP, 这个是在争取每跳最远的greedy while (cur < n - 1) { int pre = cur; while (i <= pre) { cur = max(cur, i + A[i]); ++i; } ++res; } 确定当前最远能覆盖的节点,放入curr。然后继续扫描,直到当前的路程超过了上一次算出的覆盖范围,那么更新覆盖范围,同时更新条数,因为我们是经过了多一跳才能继续前进的。

[LeetCode#91] Decode Ways 解码方法 A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 Given an encoded message containing digits, determine the total number of ways to decode it. For example, Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). The number of ways decoding "12" is 2.

DP: 限制条件,比如说一位数时不能为0,两位数不能大于26,其十位上的数也不能为0 int[] dp = new int[s.length() + 1]; dp[0] = 1; for (int i = 1; i < dp.length; ++i) { dp[i] = (s.charAt(i - 1) == '0') ? 0 : dp[i - 1]; if (i > 1 && (s.charAt(i - 2) == '1' || (s.charAt(i - 2) == '2' && s.charAt(i - 1) <= '6'))) { dp[i] += dp[i - 2]; } } return dp[s.length()]; dp[i]是表示前i个数字有多少种解析的方式,接下来来想想递归式,有两种方式:第一种新加进来的数字不然就是自己比较表示一个字符,那么解析的方式有dp[i-1]种,第二种就是新加进来的数字和前一个数字凑成一个字符,解析的方式有dp[i-2]种(因为上一个字符和自己凑成了一个)。 (1)00:dp[i]=0(无法解析,没有可行解析方式); (2)10, 20:dp[i]=dp[i-2](只有第二种情况成立); (3)11-19, 21-26:dp[i]=dp[i-1]+dp[i-2](两种情况都可行); (4)01-09, 27-99:dp[i]=dp[i-1](只有第一种情况可行);

[LeetCode#1] Two Sum 两数之和 Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution. Example: Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

HashMap

[LeetCode#53] Maximum Subarray 最大子数组 Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [−2,1,−3,4,−1,2,1,−5,4], the contiguous subarray [4,−1,2,1] has the largest sum = 6. click to show more practice. More practice: If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

O(n) curSum = max(curSum + num, num); res = max(res, curSum); O(nlgn) ????????

[LeetCode#99] Recover Binary Search Tree 复原二叉搜索树 Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Note: A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

O(n) space 用中序遍历树,并将所有节点存到一个一维向量中,把所有节点值存到另一个一维向量中,然后对存节点值的一维向量排序,在将排好的数组按顺序赋给节点。这种最一般的解法可针对任意个数目的节点错乱的情况 O(height) space 递归中序遍历 first,second分别表示第一个和第二个错乱位置的节点,pre指向当前节点的中序遍历的前一个节点 如果pre的大,若first为空,则将first指向pre指的节点,把second指向当前节点 O(0) space Morris遍历,这是一种非递归且不使用栈,空间复杂度为O(1)的遍历方法,在其基础上做些修改,加入first, second和parent指针,来比较当前节点值和中序遍历的前一节点值的大小

[LeetCode#5] Longest Palindromic Substring 最长回文串 Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

O(n*n) 两个两个的对称验证是否相等,那么对于找回文字串的问题,就要以每一个字符为中心,像两边扩散来寻找回文串 DP dp[i, j] = 1 if i == j = s[i] == s[j] if j = i + 1 = s[i] == s[j] && dp[i + 1][j - 1] if j > i + 1 O(n) Manacher's Algorithm 1. 先填充#来统一奇偶情况,并计算出的半径长度就是原字符串的回文总长度 2.P[i]将记录以i为中心的最长回文半径。从左到右计算p[i],做回文匹配,不断记录匹配过的前沿max和到达此前沿的回文中心po。 优化发生在如果要匹配的新i在前沿内(i<max),依据回文属性,找到i对于po的对应点j = po-(i-po) = 2*po-i,对以i为中心的匹配可以不用以1为半径匹配,可以直接以p[j]为半径匹配。 p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1; runtime:这样基本保证了在回文套回文的情况下,回文内部匹配信息的复用 以字符串"aaaaaaa.....a"为例,Manacher算法不会在每个新a上从半径1开始左右匹配,它会先参考i对于po的对应点j,P[j]的值,这样当i推进时,只匹配了max的下一个字符。达到了O(n)

[LeetCode#18] 4Sum 四数之和 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. Note: Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d) The solution set must not contain duplicate quadruplets. For example, given array S = {1 0 -1 0 -2 2}, and target = 0. A solution set is: (-1, 0, 0, 1) (-2, -1, 1, 2) (-2, 0, 0, 2)

O(n^3)解法的思路跟3Sum 三数之和基本没啥区别,就是多加了一层for循环,其他的都一样

[LeetCode#95] Unique Binary Search Trees II 独一无二的二叉搜索树之二 Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For example, Given n = 3, your program should return all 5 unique BST's shown below. 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ. OJ's Binary Tree Serialization: The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. Here's an example: 1 / \ 2 3 / 4 \ 5 The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".

Recursion #1每个数都可以做根,划分左右两个子树 #2每个子树执行#1 #将根和可能的左子树×可能的右子树连接起来,成为这一级子树

[LeetCode#10] Regular Expression Matching 正则表达式匹配 Implement regular expression matching with support for '.' and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "a*") → true isMatch("aa", ".*") → true isMatch("ab", ".*") → true isMatch("aab", "c*a*b") → true

Recursion - 若p为空,若s也为空,返回true,反之返回false - 若p的长度为1,若s长度也为1,且相同或是p为'.'则返回true,反之返回false - 若p的第二个字符不为*,若此时s为空返回false,否则判断首字符是否匹配,且从各自的第二个字符开始调用递归函数匹配 - 若p的第二个字符为*,若s不为空且字符匹配,调用递归函数匹配s和去掉前两个字符的p,若匹配返回true,否则s去掉首字母 - 返回调用递归函数匹配s和去掉前两个字符的p的结果 DP 定义一个二维的DP数组,其中dp[i][j]表示s[0,i)和p[0,j)是否match if (j > 1 && p[j - 1] == '*') { dp[i][j] = dp[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && dp[i - 1][j]); } else { dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.'); }

[LeetCode#17] Letter Combinations of a Phone Number 电话号码的字母组合 Given a digit string, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given below. Input:Digit string "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

Recursion Iterative

[LeetCode#22] Generate Parentheses 生成括号 Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. For example, given n = 3, a solution set is: "((()))", "(()())", "(())()", "()(())", "()()()"

Recursion ( DPS, then trim with restriction) #1 两个变量left和right分别表示剩余左右括号的个数,如果在某次递归时, if left>right, 说明此时生成的字符串中右括号的个数大于左括号的个数, 非法. if left==0 and right==0, that is it. if (left > 0) generateParenthesisDFS(left - 1, right, out + '(', res); if (right > 0) generateParenthesisDFS(left, right - 1, out + ')', res); #2 思想是找左括号,每找到一个左括号,就在其后面加一个完整的括号,最后再在开头加一个(),就形成了所有的情况,需要注意的是,有时候会出现重复的情况,所以我们用set数据结构,好处是如果遇到重复项,不会加入到结果中,最后我们再把set转为vector即可 n=1: () n=2: (()) ()() n=3: (()()) ((())) ()(()) (())() ()()()

[LeetCode#58] Length of Last Word 求末尾单词的长度 Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. If the last word does not exist, return 0. Note: A word is defined as a character sequence consists of non-space characters only. For example, Given s = "Hello World", return 5.

s.trim().length()-s.trim().lastIndexOf(" ")-1;

[LeetCode#100] Same Tree 判断相同树 Given two binary trees, write a function to check if they are equal or not. Two binary trees are considered equal if they are structurally identical and the nodes have the same value.

bool isSameTree(TreeNode *p, TreeNode *q) { if (!p && !q) return true; if ((p && !q) || (!p && q) || (p->val != q->val)) return false; return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); }

[LeetCode#90] Subsets II 子集合之二 Given a collection of integers that might contain duplicates, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,2], a solution is: [ [2], [1], [1,2,2], [2,2], [1,2], [] ]

can sort and skip duplicates

[LeetCode#92] Reverse Linked List II 倒置链表之二 Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->5->NULL. Note: Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list.

dummy head

[LeetCode#8] String to Integer (atoi) 字符串转为整数 Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. Requirements for atoi: The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.

if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - '0' > 7)) { return (sign == 1) ? INT_MAX : INT_MIN; } [Mine]当前匹配到的数base,如果就比INT_MAX的个位以上的数大了,后面还有任何数,整个数一定大于INT_MAX。 如果和INT_MAX个位前的数正好,那么各位不能超过7,因为7=INT_MAX % 10

[LeetCode#56] Merge Intervals 合并区间 Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18].

sort merge

[LeetCode#16] 3Sum Closest 最近三数之和 Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

sort 先确定一个数,然后用两个指针left和right来滑动寻找另外两个数,每确定两个数,我们求出此三数之和,然后算和给定值的差的绝对值存在newDiff中,然后和diff比较并更新diff和结果closest即可

[LeetCode#7] Reverse Integer 翻转整数 Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 click to show spoilers. Have you thought about this? Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases? For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

while (x > 0) { res = res * 10 + x % 10; x /= 10; }

[LeetCode#71] Simplify Path 简化路径 Given an absolute path for a file (Unix-style), simplify it. For example, path = "/home/", => "/home" path = "/a/./b/../../c/", => "/c" click to show corner cases. Corner Cases: Did you consider the case where path = "/../"? In this case, you should return "/". Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". In this case, you should ignore redundant slashes and return "/home/foo".

中间是"."的情况直接去掉,是".."时删掉它上面挨着的一个路径,而下面的边界条件给的一些情况中可以得知,如果是空的话返回"/",如果有多个"/"只保留一个。那么我们可以把路径看做是由一个或多个"/"分割开的众多子字符串,把它们分别提取出来一一处理即可

[LeetCode#93] Restore IP Addresses 复原IP地址 Given a string containing only digits, restore it by returning all possible valid IP address combinations. For example: Given "25525511135", return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)

也可以看做是字符串的分段问题,在输入字符串中加入三个点,将字符串分为四段,每一段必须合法,求所有可能的情况。 根据目前刷了这么多题,得出了两个经验,一是只要遇到字符串的子序列或配准问题首先考虑动态规划DP,二是只要遇到需要求出所有可能情况首先考虑用递归。 recursion.

[LeetCode#35] Search Insert Position 搜索插入位置 Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array. Here are few examples. [1,3,5,6], 5 → 2 [1,3,5,6], 2 → 1 [1,3,5,6], 7 → 4 [1,3,5,6], 0 → 0

二分搜索法

[LeetCode#33] Search in Rotated Sorted Array 在旋转有序数组中搜索 Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assume no duplicate exists in the array.

二分搜索法的关键在于获得了中间数后,判断下面要搜索左半段还是右半段,我们观察上面红色的数字都是升序的,由此我们可以观察出规律,如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的,我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留哪半边了

[LeetCode#85] Maximal Rectangle 最大矩形 Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area.

二维矩阵每一层向上都可以看做一个直方图,输入矩阵有多少行,就可以形成多少个直方图 对于每一个点,如果是'0',则赋0,如果是 '1',就赋 之前的height值加上1

[LeetCode#88] Merge Sorted Array 混合插入有序数组 Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assume that A has enough space (size that is greater or equal to m + n) to hold additional elements from B. The number of elements initialized in A and B are m and n respectively.

从最后面开始往前赋值,先比较A和B中最后一个元素的大小,把较大的那个插入到m+n-1的位置上,再依次向前推

[LeetCode#79] Word Search 词语搜索 Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. For example, Given board = [ ["ABCE"], ["SFCS"], ["ADEE"] ] word = "ABCCED", -> returns true, word = "SEE", -> returns true, word = "ABCB", -> returns false.

以二维数组中每一个数都作为起点和给定字符串做匹配,我们还需要一个和原数组等大小的visited数组,是bool型的,用来记录当前位置是否已经被访问过,因为题目要求一个cell只能被访问一次。

[LeetCode#29] Divide Two Integers 两数相除 Divide two integers without using multiplication, division and mod operator. If it is overflow, return MAX_INT.

位操作Bit Operation 除数<<1, 依靠减法和循环,被除数不断减去除数的二进制倍数,并累加这些倍数关系。直到被除数被减到小于除数。 while (m >= n) { long long t = n, p = 1; while (m >= (t << 1)) { t <<= 1; p <<= 1; } res += p; m -= t; } [Mine] 如果可以使用乘法,把这里的<<1变成X10,就非常好理解了。

[LeetCode#26] Remove Duplicates from Sorted Array 有序数组中去除重复项 Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this in place with constant memory. For example, Given input array A = [1,1,2], Your function should return length = 2, and A is now [1,2].

使用快慢指针来记录遍历的坐标,最开始时两个指针都指向第一个数字,如果两个指针指的数字相同,则快指针向前走一步,如果不同,则两个指针都向前走一步,这样当快指针走完整个数组后,慢指针当前的坐标加1就是数组中不同数组的个数

[LeetCode#32] Longest Valid Parentheses 最长有效括号 Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. For "(()", the longest valid parentheses substring is "()", which has length = 2. Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

借助栈来求解,需要定义个start变量来记录合法括号串的起始位置,我们遍历字符串,如果遇到左括号,则将当前下标压入栈,如果遇到右括号,如果当前栈为空,则将下一个坐标位置记录到start,如果栈不为空,则将栈顶元素取出,此时若栈为空,则更新结果和i - start + 1中的较大值,否则更新结果和i - 栈顶元素中的较大值

[LeetCode#39] Combination Sum 组合之和 Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited number of times. Note: All numbers (including target) will be positive integers. Elements in a combination (a1, a2, ... , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ ... ≤ ak). The solution set must not contain duplicate combinations. For example, given candidate set 2,3,6,7 and target 7, A solution set is: [7] [2, 2, 3]

写一个递归函数,这里我们新加入三个变量,start记录当前的递归到的下标,out为一个解,res保存所有已经得到的解,每次调用新的递归函数时,此时的target要减去当前数组的的数

[LeetCode#36] Valid Sudoku 验证数独 Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character '.'. Note: A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

判断标准是看各行各列是否有重复数字,以及每个小的3x3的小方阵里面是否有重复数字,如果都无重复,则当前矩阵是数独矩阵,但不代表待数独矩阵有解,只是单纯的判断当前未填完的矩阵是否是数独矩阵。

[LeetCode#40] Combination Sum II 组合之和之二 Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. Each number in C may only be used once in the combination. Note: All numbers (including target) will be positive integers. Elements in a combination (a1, a2, ... , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ ... ≤ ak). The solution set must not contain duplicate combinations. For example, given candidate set 10,1,2,7,6,1,5 and target 8, A solution set is: [1, 7] [1, 2, 5] [2, 6] [1, 1, 6]

在递归的for循环里加上if (i > start && num[i] == num[i - 1]) continue; 这样可以防止res中出现重复项,然后就在递归调用combinationSum2DFS里面的参数换成i+1,这样就不会重复使用数组中的数字了

[LeetCode#44] Wildcard Matching 外卡匹配 Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. '*' Matches any sequence of characters (including the empty sequence). The matching should cover the entire input string (not partial). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "*") → true isMatch("aa", "a*") → true isMatch("ab", "?*") → true isMatch("aab", "c*a*b") → false

外卡匹配和正则匹配最大的区别就是在星号的使用规则上,对于正则匹配来说,星号不能单独存在,前面必须要有一个字符,而星号存在的意义就是表明前面这个字符的个数可以是任意个,包括0个,那么就是说即使前面这个字符并没有在s中出现过也无所谓,只要后面的能匹配上就可以了。而外卡匹配就不是这样的,外卡匹配中的星号跟前面的字符没有半毛钱关系,如果前面的字符没有匹配上,那么直接返回false了,根本不用管星号。而星号存在的作用是可以表示任意的字符串,当然只是当匹配字符串缺少一些字符的时候起作用,当匹配字符串包含目标字符串没有的字符时,将无法成功匹配。 DP 定义一个二维的DP数组,其中dp[i][j]表示s[0,i)和p[0,j)是否match if (p[j - 1] == '*') { dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; } else { dp[i][j] = (s[i - 1] == p[j - 1] || p[j - 1] == '?') && dp[i - 1][j - 1]; }

[LeetCode#81] Search in Rotated Sorted Array II 在旋转有序数组中搜索之二 Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array.

如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的。而如果可以有重复值,中间值等于最右值时,只要把最右值向左一位即可继续循环,如果还相同则继续移,直到移到不同值为止

[LeetCode#13] Roman to Integer 罗马数字转化成整数 Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.

对于Ⅻ 和IIX的区别 可以每次跟前面的数字比较,如果小于等于前面的数字,我们先加上当前的数字,如果大于的前面的数字,我们加上当前的数字减去二倍前面的数字,这样可以把在上一个循环多加数减掉

[LeetCode#38] Count and Say 计数和读法 The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, 1211, 111221, ... 1 is read off as "one 1" or 11. 11 is read off as "two 1s" or 21. 21 is read off as "one 2, then one 1" or 1211. Given an integer n, generate the nth sequence. Note: The sequence of integers will be represented as a string.

对于前一个数,找出相同元素的个数,把个数和该元素存到新的string里

[LeetCode#34] Search for a Range 搜索一个范围 Given a sorted array of integers, find the starting and ending position of a given target value. Your algorithm's runtime complexity must be in the order of O(log n). If the target is not found in the array, return [-1, -1]. For example, Given [5, 7, 7, 8, 8, 10] and target value 8, return [3, 4].

对原数组使用二分查找法,找出其中一个目标值的位置,然后向两边搜索找出起始和结束的位置

[LeetCode#15] 3Sum 三数之和 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) The solution set must not contain duplicate triplets. For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2)

对原数组进行排序 转换为2Sum 找一个负数,作为target(零减),在剩下的有序数组中,左右indx向target微调

[LeetCode#84] Largest Rectangle in Histogram 直方图中最大的矩形 Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The largest rectangle is shown in the shaded area, which has area = 10 unit. For example, Given height = [2,1,5,6,2,3], return 10.

当前值小于栈顶值时,取出栈顶元素,然后计算当前矩形面积,然后再对比当前值和新的栈顶值大小,若还是栈顶值大,则再取出栈顶,算此时共同矩形区域面积,照此类推,可得最大矩形 [Mine]形成矩形是在直方图高度下降时。用栈找到下降处,并计算其和之前比他高的上升沿所围成的矩形面积

[LeetCode#63] Unique Paths II 不同的路径之二 Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid. For example, There is one obstacle in the middle of a 3x3 grid as illustrated below. [ [0,0,0], [0,1,0], [0,0,0] ] The total number of unique paths is 2. Note: m and n will be at most 100.

当遇到为1的点,将该位置的dp数组中的值清零

[LeetCode#50] Pow(x, n) 求x的n次方 Implement pow(x, n).

我们可以用递归来折半计算,每次把n缩小一半,这样n最终会缩小到0,任何数的0次方都为1,这时候我们再往回乘,如果此时n是偶数,直接把上次递归得到的值算个平方返回即可,如果是奇数,则还需要乘上个x的值。还有一点需要引起我们的注意的是n有可能为负数,对于n是负数的情况,我们可以先用其绝对值计算出一个结果再取其倒数即可

[LeetCode#25] Reverse Nodes in k-Group 每k个一组翻转链表 Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. You may not alter the values in the nodes, only nodes itself may be changed. Only constant memory is allowed. For example, Given this linked list: 1->2->3->4->5 For k = 2, you should return: 2->1->4->3->5 For k = 3, you should return: 3->2->1->4->5

我们大多时候都会在开头再加一个dummy node,因为翻转链表时头结点可能会变化,为了记录当前最新的头结点的位置而引入的dummy node 需要两个函数,一个是用来分段的,一个是用来翻转的

[LeetCode#6] ZigZag Converesion 之字型转换字符串 The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line: "PAHNAPLSIIGYIR" Write the code that will take a string and make this conversion given a number of rows: string convert(string text, int nRows); convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".

找规律 row = nRows column = 2 * nRows - 2 找到竖排的字符。 对于对角的字符,每个对角元素的位置为 j + 2*nRows-2 - 2*i, 其中,j为前一个竖排元素的列数,i为当前行数 [Mine]用index写例子,找规律。 对角字符就是下一个竖排字符向回找二倍的当前行数

[LeetCode#3] Longest Substring Without Repeating Characters 最长无重复子串 Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

把出现过的字符都放入set中,遇到set中没有的字符就加入set中并更新结果res,如果遇到重复的,则从左边开始删字符,直到删到重复的字符停止

[LeetCode#43] Multiply Strings 字符串相乘 Given two numbers represented as strings, return multiplication of the numbers as a string. Note: The numbers can be arbitrarily large and are non-negative.

把错位相加后的结果保存到一个一维数组中,然后分别每位上算进位,最后每个数字都变成一位,然后要做的是去除掉首位0,最后把每位上的数字按顺序保存到结果中即可

[LeetCode#59] Spiral Matrix II 螺旋矩阵之二 Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For example, Given n = 3, You should return the following matrix: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]

按螺旋的顺序来填数, 由于给定矩形是个正方形,我们计算环数时用n / 2来计算,若n为奇数时,此时最中间的那个点没有被算在环数里,所以最后需要单独赋值

[LeetCode#21] Merge Two Sorted Lists 混合插入有序链表 Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

新建一个链表,然后比较两个链表中的元素值,把较小的那个链到新链表中,由于两个输入链表的长度可能不同,所以最终会有一个链表先完成插入所有元素,则直接另一个未完成的链表直接链入新链表的末尾。

[LeetCode#55] Jump Game 跳跃游戏 Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Determine if you are able to reach the last index. For example: A = [2,3,1,1,4], return true. A = [3,2,1,0,4], return false.

有一个非负整数的数组,每个数字表示在当前位置的基础上最多可以走的步数,求判断能不能到达最后一个位置,开始我以为是必须刚好到达最后一个位置,超过了不算,其实是理解题意有误,因为每个位置上的数字表示的是最多可以走的步数而不是像玩大富翁一样摇骰子摇出几一定要走几步。 DP

[LeetCode#65] Valid Number 验证数字 Validate if a given string is numeric. Some examples: "0" => true " 0.1 " => true "abc" => false "1 a" => false "2e10" => true Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

有利用有限自动机Finite Automata Machine的程序写的简洁优雅 有利用正则表达式,更是写的丧心病狂的简洁 String regex = "[-+]?(\\d+\\.?|\\.\\d+)\\d*(e[-+]?\\d+)?";

[LeetCode#20] Valid Parentheses 验证括号 Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.

[LeetCode#37] Sudoku Solver 求解数独 Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character '.'. You may assume that there will be only one unique solution.

此题类似的有 Permutations 全排列,Combinations 组合项, N-Queens N皇后问题等等,其中尤其是跟 N-Queens N皇后问题的解题思路及其相似,对于每个需要填数字的格子带入1到9,每代入一个数字都判定其是否合法,如果合法就继续下一次递归,结束时把数字设回'.'

[LeetCode#89] Gray Code 格雷码 The gray code is a binary numeral system where two successive values differ in only one bit. Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: 00 - 0 01 - 1 11 - 3 10 - 2 Note: For a given n, a gray code sequence is not uniquely defined. For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.

用到了一个set来保存已经产生的结果,我们从0开始,遍历其二进制每一位,对其取反,然后看其是否在set中出现过,如果没有,我们将其加入set和结果res中,然后再对这个数的每一位进行遍历,以此类推就可以找出所有的格雷码了 [mine]每一次对单独一位取反,对新结果再对每一位取反,直到没有新结果出来

[LeetCode#9] Palindrome Number 验证回文数字 Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could negative integers be palindromes? (ie, -1) If you are thinking of converting the integer to string, note the restriction of using extra space. You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case? There is a more generic way of solving this problem.

直接对整数进行操作,我们可以利用取整和取余来获得我们想要的数字 while (x / div >= 10) div *= 10; ....... int left = x / div; int right = x % 10;

[LeetCode#14] Longest Common Prefix 最长共同前缀 Write a function to find the longest common prefix string among an array of strings.

纵向逐列遍历

[LeetCode#51] N-Queens N皇后问题 The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other. Given an integer n, return all distinct solutions to the n-queens puzzle. Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively. For example, There exist two distinct solutions to the 4-queens puzzle: [ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ]

经典解法为回溯递归,一层一层的向下扫描,需要用到一个pos数组,其中pos[i]表示第i行皇后的位置,初始化为-1,然后从第0开始递归,每一行都一次遍历各列,判断如果在该位置放置皇后会不会有冲突,以此类推,当到最后一行的皇后放好后,一种解法就生成了,将其存入结果res中,然后再还会继续完成搜索所有的情况

[LeetCode#67] Add Binary 二进制数相加 Given two binary strings, return their sum (also a binary string). For example, a = "11" b = "1" Return "100".

补0,换成等长字符串 carry

[LeetCode#11] Container With Most Water 装最多水的容器 Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. Note: You may not slant the container.

让求最大的一个的装水量 定义i和j两个指针分别指向数组的左右两端,然后两个指针向中间搜索,每移动一次算一个值和结果比较取较大的,容器装水量的算法是找出左右两个边缘中较小的那个乘以两边缘的距离, while (i < j) { res = max(res, min(height[i], height[j]) * (j - i)); height[i] < height[j] ? ++i : --j; }

[LeetCode#77] Combinations 组合项 Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For example, If n = 4 and k = 2, a solution is: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]

这种要求出所有结果的集合,一般都是用DFS调用递归来解。那么我们建立一个保存最终结果的大集合res,还要定义一个保存每一个组合的小集合out,每次放一个数到out里,如果out里数个数到了k个,则把out保存到最终结果中,否则在下一层中继续调用递归。

[LeetCode#80] Remove Duplicates from Sorted Array II 有序数组中去除重复项之二 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For example, Given sorted array A = [1,1,1,2,2,3], Your function should return length = 5, and A is now [1,1,2,2,3].

这里允许最多重复的次数是两次,那么我们就需要用一个变量count来记录还允许有几次重复,count初始化为1,如果出现过一次重复,则count递减1,那么下次再出现重复,快指针直接前进一步,如果这时候不是重复的,则count恢复1,由于整个数组是有序的,所以一旦出现不重复的数,则一定比这个数大,此数之后不会再有重复项。

[LeetCode#46] Permutations 全排列 Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].

递归DFS #1 需要用到一个visited数组来标记某个数字是否访问过 #2 这里是每次交换num里面的两个数字,经过递归可以生成所有的排列情况 [Mine]以上两种情况都是用在visited数组中挑选或swap的方式给指定位置选数字,两种方法都保证了每个数字在每个位置上都会出现。 #3 From CareerCup 当n=1时,数组中只有一个数a1,其全排列只有一种,即为a1 当n=2时,数组中此时有a1a2,其全排列有两种,a1a2和a2a1,那么此时我们考虑和上面那种情况的关系,我们发现,其实就是在a1的前后两个位置分别加入了a2 当n=3时,数组中有a1a2a3,此时全排列有六种,分别为a1a2a3, a1a3a2, a2a1a3, a2a3a1, a3a1a2, 和 a3a2a1。那么根据上面的结论,实际上是在a1a2和a2a1的基础上在不同的位置上加入a3而得到的。

[LeetCode#69] Sqrt(x) 求平方根 Implement int sqrt(int x). Compute and return the square root of x.

采用二分搜索法来找平方根 long long left = 0, right = (x / 2) + 1; while (left <= right) { long long mid = (left + right) / 2; long long sq = mid * mid; if (sq == x) return mid; else if (sq < x) left = mid + 1; else right = mid - 1; } return right;

[LeetCode#82] Remove Duplicates from Sorted List II 移除有序链表中的重复项之二 Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->3->3->4->4->5, return 1->2->5. Given 1->1->1->2->3, return 2->3.

需要定义一个新的节点,然后链上原链表,然后定义一个前驱指针和一个现指针,每当前驱指针指向新建的节点,现指针从下一个位置开始往下遍历,遇到相同的则继续往下,直到遇到不同项时,把前驱指针的next指向下面那个不同的元素。如果现指针遍历的第一个元素就不相同,则把前驱指针向下移一位。

[LeetCode#83] Remove Duplicates from Sorted List 移除有序链表中的重复项 Given a sorted linked list, delete all duplicates such that each element appear only once. For example, Given 1->1->2, return 1->2. Given 1->1->2->3->3, return 1->2->3.

需要定义个指针指向该链表的第一个元素,然后第一个元素和第二个元素比较,如果重复了,则删掉第二个元素,如果不重复,指针指向第二个元素。这样遍历完整个链表,则剩下的元素没有重复项

[LeetCode#75] Sort Colors 颜色排序 Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. Note: You are not suppose to use the library's sort function for this problem. click to show follow up. Follow up: A rather straight forward solution is a two-pass algorithm using counting sort. First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. Could you come up with an one-pass algorithm using only constant space?

题目中还要让只遍历一次数组来求解,那么我需要用双指针来做,分别从原数组的首尾往中心移动。

[LeetCode#66] Plus One 加一运算 Given a non-negative number represented as an array of digits, plus one to the number. The digits are stored such that the most significant digit is at the head of the list.

首先判断最后一位是否为9,若不是,直接加一返回,若是,则该位赋0,再继续查前一位,同样的方法,知道查完第一位。如果第一位原本为9,加一后会产生新的一位

[LeetCode#86] Partition List 划分链表 Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. You should preserve the original relative order of the nodes in each of the two partitions. For example, Given 1->4->3->2->5->2 and x = 3, return 1->2->2->4->3->5.

首先找到第一个大于或等于给定值的节点,用题目中给的例子来说就是先找到4,然后再找小于3的值,每找到一个就将其取出置于4之前即可


Set pelajaran terkait

macro econ review questions chapter 13

View Set

Las Preguntas (Question to Answers)

View Set

NCLEX 10000 Musculoskeletal Disorders

View Set

(1.1) Types of Changes and Accounting Approaches

View Set

Performance by chapter What's this? Chapter 61: Management of Patients with Dermatologic Disorders

View Set