zoukankan      html  css  js  c++  java
  • leetcode 学习心得 (1) (24~300)

    源代码地址:https://github.com/hopebo/hopelee

    语言:C++

    24.Swap Nodes in Pairs

    Given a linked list, swap every two adjacent nodes and return its head.

    For example,
    Given 1->2->3->4, you should return the list as 2->1->4->3.

    Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

    第一次提交BUG FREE,用的是简单逻辑方法。最佳提交答案用的是递归的方式。

    25.Reverse Nodes in k-Group

    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

    k is a positive integer and is less than or equal to the length of the linked 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

    答题思路:选取前k个节点作为一组,用vector向量来存储指向每个结点的指针。使用递归的方法,将head结点next指针指向前k个结点后结点链的反转返回指针,将前k个节点指针指向反转后返回第k个结点即可。

    第一次提交未考虑特殊情况,初始指针指向为空的情况;

    第二次提交未考虑k=1的情况,这种情况下不用进行任何操作返回即可;

    第三次提交出现指针向量访问越界;

    第四次提交BUG FREE。

    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 nums = [1,1,2],

    Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.

    第一次提交以为要缩短原向量长度,仅保留由不同数字组成的向量,用到STL中vector的erase(iterator front,iterator last)方法,删除两个迭代器[front,last)之间的所有元素,并返回下一后续元素的迭代器。AC

    第二次提交意识到并不需要改变原向量,仅需将不同数字存储在向量的前面即可。AC

    27. Remove Element

    Given an array and a value, remove all instances of that value in place and return the new length.

    Do not allocate extra space for another array, you must do this in place with constant memory.

    The order of elements can be changed. It doesn't matter what you leave beyond the new length.

    Example:
    Given input array nums = [3,2,2,3]val = 3

    Your function should return length = 2, with the first two elements of nums being 2.

    第一次提交忽略数组长度为0,为1的特殊情况。以后写完代码,一定要对特殊情况进行代入检查。

    解题思路:

    对数组从前往后遍历,用一个begin变量记录不等于val的数组长度以及位置;用变量i进行循环,如果与val相等则继续循环,如果不等于val,则赋给begin变量指向的数组位置;直到对整个数组遍历一遍。

    28. Implement strStr()

    Implement strStr().

    Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

    第一次提交出现变量未定义的编译错误,原因在于对for循环中的循环变量在循环结束后访问其数值以得知循环状态,这种情况下一定要在循环前就定义循环变量,如果在循环内部定义,循环结束后会自动释放。

    第二次提交对特殊情况的返回结果把握有误,在""寻找""和在"a"寻找""结果都返回0,但是在""寻找"a"返回结果-1。

    解题思路:

    对模式串的各个字符依次与目标串进行比较,如果不同则从目标串的下一字符开始比较,为brute-force算法。

    改进的KMP算法思路:在一次匹配失败后尽可能地将目标串开始位置右移,位移的距离为已匹配子串中相邻相同字符的最长长度。(对于相同字符而言,位移的意义是将前一个字符的位置匹配到后一个字符上去,既然是相邻的字符,如果不移动这么长的距离,肯定是匹配不上,因为之间没有相同字符。)

    29. Divide Two Integers

    Divide two integers without using multiplication, division and mod operator.

    If it is overflow, return MAX_INT.

    第一次提交忘记给相除后的绝对值结果加上符号。

    第二次提交对<<运算符的理解有误,直接使用例如temp<<1语句不会对temp产生实质性的更改,必须将结果重新赋给原变量。

    第三次提交将int型变量temp,temp+temp的值与其他变量值进行比较,可能导致溢出的情况,因为temp+temp默认是用原变量类型标识,应该初始定义temp为long int。

    解题思路:

    1. 对int型被除数与除数的除法问题,首先要考虑溢出情况,除数为0或者最小负数除-1。INT_MIN在取绝对值时也需考虑溢出。
    2. 在不能使用乘、除、取余运算的时候,考虑用移位运算符来实现除数的快速增加,和被除数进行比较相减。

    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).

    第一次提交由于给定函数的参数数量和类型,尝试递归调用失败。

    第二次提交存在未定义变量类型的问题,可能是python用多了,在C++中使用过的所有变量都必须提前定义变量类型。

    第三次提交循环控制条件用n-wl时,一定是<=,而不是<。

    解题思路:

    1. 由于所要寻找的子字符串中需要包含目标单词向量中所有次数的单词,而不约束单词出现的顺序。因此采用map结构进行存储比较方便,对应单词出现对应次数即可。
    2. 当当前子串某个单词出现次数超过其向量中次数时,便调整子串的起始位置。

    31. Next Permutation

    Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

    If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

    The replacement must be in-place, do not allocate extra memory.

    Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
    1,2,3 → 1,3,2
    3,2,1 → 1,2,3
    1,1,5 → 1,5,1

    第一次提交在理解题意上存在有误,需要调换顺序使ASCII码的顺序上升且仅上升一位。

    第二次提交需要注意反复执行同样功能的代码段写成函数的形式会使代码的执行效率更高。

    解题思路:

    1. 从末尾反转遍历数组,直至出现比后一个值小的位置,便可以在该位置进行交换。
    2. 交换的时候需要正向遍历直至找到刚好大于该位置的最小值,注意交换后,需要重新将后面的从大到小的数组重新排列,使从小到大的顺序。

    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.

    第一次提交考虑问题不够完善,有效的括号可能中间会出现中断的情况。

    解题思路:

    1. 定义一个栈空间,用来存储'('和')'的位置信息,代表着整个字符串列表中出现连续有效括号中断的位置,如果没有中断,会在读取的过程中pop出去。
    2. 对字符串遍历完毕后,求每个中断之间的距离,为连续有效括号的长度,取最长长度为所求值。

    回顾记录:

    1. 第一次回顾时没有思路。

    33. Search in Rotated Sorted Array

    Suppose an array sorted in ascending order 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.

    第一次思维很混乱,总想着low和high是逻辑层面上的数组序列号,而不是实际层面的,事实证明这样导致判断变得十分麻烦。

    解题思路:

    1. 元素查找一定尽量选择使用二分法,使查找效率最大化。low和high就是实际层面上的最左端和最右端。
    2. 本题,首先将nums[mid]与nums[low]进行比较来得到mid究竟是处于哪一部分数列中,然后再将nums[mid]与target进行比较得到下一步low和high的变化方式。

    34. Search for a Range

    Given an array of integers sorted in ascending order, 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].

    第一次虽然思维很混乱,但是写出来了,是先查找到一个值,然后再分成两部分分别使用二分法查找的,虽说避免了第一次查找的冗余,但是代码出现重复的部分,而且判断条件比较混乱,是通过比较当前查找到的位置与前一个位置或者后一个位置上的值是否相等来判断左边界和右边界的。

    解题思路:

    1. 对整个向量数组进行两次二分查找,分别找到target左边界位置和右边界位置。在这里要特别注意两种情况下,lo和hi的改变方式。

    34. Search for a Range

    Given an array of integers sorted in ascending order, 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].

    解题思路:

    1. 二分法遍历,循环条件一定要写成<=!

    关于二分法遍历的感想总结:

    1. 最普通的二分法遍历,循环条件需写成low<=high,这样循环才会判断向量中的所有元素,包括最后一次low=high的情况。否则,最后一个元素会有所缺漏,不会判断。
    2. 一般mid作为临时变量,在循环中定义和计算即可。一般mid=(low+high)/2,由于整数的性质,当low=high-1时,会使mid优先选择mid,当改变为low=mid+1和high=mid-1时没有问题,但是当改变为low=mid时会出现无限循环的情况,针对不同的题目,可灵活改变判断条件和mid的计算值比如mid=(low+high)/2+1.

    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 '.'.

    A partially filled sudoku which is valid.

    Note:
    A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

    第一次尝试用map和set相结合的存储结构处理数据,但是set数组的结构不存在。

    解题思路:

    用数组来代替set结构,每次存入数据前,访问当前位置上是否有值来达到和set结构相同的效果。三个数组分别代表数独结构的行、列和子区域。

    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.

    A sudoku puzzle...

    ...and its solution numbers marked in red.

    第一次在字符和数字的转换上出现了严重错误,没有正确对应上,导致在其他地方出现错误还不好发现。以后一定要弄清楚给字符类型变量传入的是字符还是数。

    解题思路:

    1. 采用递归和循环能够对数独游戏进行暴力破解,而且代码量不大。
    2. 在简单递归的基础上,每次都对当前数独各个位置可填入数进行统计,优先选择可选择性小的位置进行填入,能够省去很多不必要的循环和递归。
    3. 当给定函数的参数设置不符合要求时,可重新定义主函数,用规定函数直接调用其即可。

    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.

    解题思路:

    1. 一定要注意string类型成员函数的使用,string类型可直接相互赋值。但是string.append()函数必须要求函数参数也为string类型。
    2. 如果是添加字符串,直接用append(char*)即可;如果是添加整型数,可以用append(to_string(int))函数;如果是添加单个字符,可以用append(to_string(char-'1'+1))进行转换,或者定义一个string类型进行初始化,string test(1,'a')。

    39. Combination Sum

    Given a set of candidate numbers (C) (without duplicates) 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.
    • 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]
    ]

    第一次使用递归循环的方式较复杂,没有按照顺序而是全局进行递归,导致同样的组合出现很多次。
    第二次向量构造函数的参数把握错误,第一个参数是指多少个。
    第三次普通变量类型的向量判断是否相等可以直接用等号,自定义类型需要重载运算符。
    解题思路:
    1. 对数字集合进行递归调用,如果一个数字可以取用无限次,那么嵌套的函数依然从当前位置开始就可以了。
    2. 暂时保留的变量,需要每层嵌套函数都能独立使用的变量就用值传递的方式;需要对总的结果进行更改就用地址传递,在主函数体定义变量,然后传递地址给递归函数。

    重写记录:

    第一次 NO BUG FREE

    第二次 BUG FREE

    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.
    • 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]
    ]
    

    第一次把问题考虑的太简单,由于给的整数向量中存在重复的数,且每个数只能使用一次,如果不加限制会出现重复的结果。

    解题思路:

    1. 采用递归的方式去解题,如果当前位置上的值与前面的值相同,但是是begin开始的话,说明没有经过回溯,需要进行嵌套调用;如果值相同,且此时位置不是begin,说明经过了回溯,前面加入与当前位置相同值时的情况已经探讨完毕,这时不用再继续讨论,直接continue。

    刷题记录:

    第一次 NO BUG FREE

    第二次 BUG FREE

    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. 对于求第一个缺失的正整数而言,只有1-size的整数是有影响的,因此把它们移到相应的位置上,直到对应的位置已经存在同样的数或者交换得到当前的数是无用的。

    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.

    The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

    解题思路:

    1. 从两边同时向中间进行循环,左边较高,右边的空缺即可全部承载从右向左;右边较高,左边的空缺即可全部填充,从左到右循环。

    43. Multiply Strings

    Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2.

    Note:

    1. The length of both num1 and num2 is < 110.
    2. Both num1 and num2 contains only digits 0-9.
    3. Both num1 and num2 does not contain any leading zero.
    4. You must not use any built-in BigInteger library or convert the inputs to integer directly.

    解题思路:

    1. 用字符串表示的整数相乘要注意观察特点,位置i和位置j的数字相乘,最终的结果会加在(i+j)的位置上,所以可以按照此规律依次把结果每一位上的数字算出来。
    2. 要注意特殊情况,题目中只说明给定数字字符串不会以'0'开头,但是有可能本身就代表着“0”,此时结果为“0",为特殊情况。

    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

    解题思路:
    1. 此题用递归的方式在理论上是可解的,但是会由于循环迭代导致Time Limit Exceeded问题。其次要注意多个连着的'*'等价于一个'*',此题更关注与模式字符串中非'*'的字符与匹配字符串的匹配。
    2. 用循环来替代递归可大幅度降低时间复杂度,记录上一个'*'的位置,依次循环匹配匹配字符串中的字符数,观察非'*'是否匹配,如果不匹配,则'*'多匹配一个,从匹配字符串的下一个位置开始匹配。

    刷题记录:

    第一次 NO BUG FREE

    第二次 BUG FREE

    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.)

    Note:
    You can assume that you can always reach the last index.

    解题思路:

    1. 利用BFS(breadth first search)广度优先搜索的策略去解决,对每一层的点遍历,就找出能达到的下一层所有的点。直到能达到最后一个点为止,此时的level层数,即为step步数。

    46. Permutations

    Given a collection of distinct 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],
      [3,2,1]
    ]

    解题思路:

    1. 利用迭代的方式,依次交换原向量中各数的位置,形成新的向量排列。

    刷题记录:

    第一次 NO BUG FREE

    第二次 BUG FREE

    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],
      [2,1,1]
    ]

    刷题记录:

    第一次 用地址传递时,需要把在迭代中交换的元素重新交换回来成为原向量。NO BUG FREE

    第二次 不使用map的方法,使用递增序列交换的方法隐藏着很多处理细节,首先是每次迭代函数中,循环的交换效果要保留,才能使后面的序列一直呈现递增序列。其次递归调用中返回的序列又必须恢复上层函数时的状态,所以只能用值传递的方式。相同的值是否已交换不能和前一个位置上的值比较,因为前一个位置上的值可能是刚交换过来的前一种值,直接与首位上的值进行比较即可,因为是从小到大进行交换。NO BUG FREE

    解题思路:

    1. 对于数组的重排列问题,由于数组中存在重复的元素,所以在交换迭代时需要考虑当前的数是否已经交换过,用一个字典来表示。
    2. 或者按照最优方法所展示的那样,将数组进行从小到大排列,每次交换后的数组除了第一位仍然是从小到大的,所以不用担心生成重复的排列。

    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. 矩阵的90°旋转,只要弄清楚每个点对应旋转后在矩阵中的位置关系即可。每个点旋转4次会回到原点,形成一个圈,因此可以把四个点放在一起讨论,定义一个int temp变量,即可完成矩阵内部的转换。
    2. 每个小正方形为一个循环。

    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. 由相同字符组成的字符串排序后的结果应该是一样的,因此利用这一点加上map字典就可以知道当前字符串的字符组成是否已经出现过。

    50. Pow(x, n)

    Implement pow(xn).

    解题思路:

    1. 采用位运算符,观察n在哪些bit位上是有1的,来进行循环。

    第一次 NO BUG FREE

    51. N-Queens

    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.."]
    ]
    

    解题思路:

    1. 八皇后问题的规则是,除了每一行、每一列,以每个皇后自己为中心的斜45°和135°的对角线上都不存在其他的皇后。因此可以对行进行循环,对每列是否已经存在皇后进行存储,对所有的45°和135°的斜线情况进行存储,在判断的时候,只需要对该点所处的斜线上的情况进行访问即可。这些用向量的数据结构都可以实现。
    2. 最简单的暴力破解法,迭代深度优先遍历。

    52. N-Queens II

    Follow up for N-Queens problem.

    Now, instead outputting board configurations, return the total number of distinct solutions.

    解题思路:

    1. 和上题基本一样,比上题简单的多,同样是构造列向量、斜45°向量和斜135°向量来存储每个位置上是否存在八皇后。不用对皇后的具体位置信息进行存储,只需要满足条件时给统计数字加1就好。

    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.

    解题思路:

    1. 从前往后进行遍历,注意在何种情况下需要重新给sum赋值,何种情况下需要比较当前sum和最大sum.

    54. Spiral Matrix

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

    For example,
    Given the following matrix:

    [
     [ 1, 2, 3 ],
     [ 4, 5, 6 ],
     [ 7, 8, 9 ]
    ]
    

    You should return [1,2,3,6,9,8,7,4,5].

    解题思路:
    1. 循环一圈一圈的读取即可,注意根据矩阵的维度确定循环次数以及是否最后一圈不完整的情况。

    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.

     
    解题思路:
    1. 使用广度优先遍历的方法,讨论当前层经过下一跳能够达到的下一层的最远距离,如果最远距离达到了最后一个点,就返回true。没有则继续讨论下一层点。
     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].

     
    解题思路:
    1. 在类的成员函数中使用sort,并引入自定义的比较函数时,需要将比较函数定义为类的静态成员函数才可以用类名来使用。或者写成以下这种形式:sort(ins.begin(), ins.end(), [](Interval a, Interval b){return a.start < b.start;}),Interval为自定义结构体变量。
    2. 这个题不要给sort函数执行的功能太多,会导致时间溢出的问题,刚开始的时候自定义sort的比较函数会使结构体变量不仅按照start递增的顺序排列,而且start相同时,希望内部按照end递增的顺序排列,这个使sort函数的执行功能过多,导致时间溢出。最后发现只需要对结构体变量按照start递增的顺序排列,定义max变量存储最大范围即可。

    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].

     
    解题思路:
    1. 本题其实就是简单的查找插入范围的start和end分别在原向量中位置,进行合并就好。但是我想复杂了,面对数据集庞大的情况,我采用的是二分查找的方式,但是由于本题的特殊性,二分查找带来的是繁琐的结果处理和判断过程。其实本题由于要对向量进行增删,所以时间复杂度一定是O(n)量级的,因此采用顺序查找并不会增加额外的时间复杂度。
    2. 此题最简单的方式是将插入间隔的start与原向量的end比较,插入间隔的end与原向量的start比较。

    第一次 BUG FREE 但是使用的方法比较复杂,需要重写一遍。

    第二次 重写还是没有找到最优的方法,需要再重写一遍

    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.

     
    解题思路:
    1. 从字符串的尾部往前遍历,找到第一次不为' '的字符,为最后一个字符串的尾部;继续向前循环,找到第一个为' '的位置,即为最后一个单词头部的前一个位置。两个位置相减,即为最后一个单词的长度。

    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 ]
    ]
    

    解题思路:

    1. 从外围到内围,一圈一圈循环填入对应的数值。

    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):

    1. "123"
    2. "132"
    3. "213"
    4. "231"
    5. "312"
    6. "321"

    Given n and k, return the kth permutation sequence.

    Note: Given n will be between 1 and 9 inclusive.

    解题思路:

    1. 每一个数字开头,后面接的排列数是可以计算的,为(n-1)!。因此通过k-1/(n-1)!就可以知道第一个数字为什么,之后的数字可以类比得到。
    2. 需要注意的问题:在循环进行之前,首先将k--,得到的结果代表着才是在第k个数字之前的数字个数;每次取用了一个数字之后剩下数字的由小到大的排列顺序要通过数据结构反映出来,最好的方法是用vector.remove(index)函数,该函数并不会对向量产生实际的增删效果,只会把当前index之后的数字往前移,使剩下的数字都处于vector的前列,且同样是处于由小到大的顺序。

    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. 该题的意思是将后k个结点循环右移,由于参数只有指向头结点的指针,因此第一次遍历得到指针链的长度是必要的。之后再做一次遍历就可以找到旋转的位置;为了避免第二次重复的遍历,用空间来换时间,可定义结点指针向量,这样遍历一次过后就可快速访问对应的位置。

     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.

    解题思路:

    1. 从左上角到右下角,一共要走(m+n-2)步,其中(m-1)步向下,(n-1)步向右。因此可以用数学公式来求解这个问题,为C(m+n-2,m-1)种解法,这种方法要注意的是,阶乘运算极其容易导致数值过大而超出变量的表示范围,所以不要把阶乘计算出来后再相除,利用循环,边乘边相除,能降低表示数据的大小,避免发生溢出。
    2. 第二种方法是动态规划DP(Dynamic Programming)问题,走到位置(i,j)的方式有两种:1、从(i-1,j)向下;2、从(i,j-1)向右;因此路径条数等于到(i-1,j)的路径条数加上(i,j-1)的路径条数。

    刷题过程:

    第一次 使用排列组合公式,数的表示范围总超出,比较混乱,需重写一遍。

    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的思路很容易解题,遇到障碍点,直接赋值路径数为0.

    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.

    解题思路:

    1. 到每个点的最小和,为到其上一个点和其左边一个点的和的较小值加上该点当前的数值。

    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.

     
    解题思路:
    1. 这种题型按照顺序把所有可能的情况分析清楚就可以了,要注意的是题意中'.'后不接数字是有效的,直接接'e'也是有效的。

     刷题记录:

    1. 按照自己的想法来,没有把状态和可能性讨论清楚就放弃了,遵循答案,虽然逻辑简单,但是比较过程较复杂。
    2. 最好用状态的方法重新做一次,不管是状态和可能性相结合还是根据看到的字符来讨论前面已出现的能否成立。重写一次

    66. Plus One

    Given a non-negative integer represented as a non-empty array of digits, plus one to the integer.

    You may assume the integer do not contain any leading zero, except the number 0 itself.

    The digits are stored such that the most significant digit is at the head of the list.

    解题思路:

    1. 从向量的尾部往前遍历,找到第一个不为9的位置,加一即可。后方为9的位置改0。

    67. Add Binary

    Given two binary strings, return their sum (also a binary string).

    For example,
    a = "11"
    b = "1"
    Return "100".

     
    解题思路:
    1. 此题从二进制字符字符串末尾往前遍历,定义一个int变量CF来表示是否有进位。注意字符与数字之间的转换即可。

    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 L characters.

    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.

    解题思路:

    1. 题目的意思是:在求每个line能容纳的单词数时要考虑每两个词之间至少需要有一个空格,不能紧挨着;最后一行每个单词的间隔为一个空格,剩下的空格全放置在右边;当某一行只能容纳一个单词时,所有的空格都放在右边。
    2. 学会一些缩减代码长度和变量定义量的方法:tmp += string((L - l) / (k - 1) + (j < (L - l) % (k - 1)), ' ');加string类型变量直接在右边使用string函数就好,将逻辑值代入数值运算中可以减少if else的判断语句,true在数值运算中为1,false为0。

    69. Sqrt(x)

    mplement int sqrt(int x).

    Compute and return the square root of x.

     解题思路:
    1. 用二分法就可以解,最后相除得到的两个整型数的差的绝对值一定为1。
    2. 此题的几个坑:首先当给出的参数为INT_MAX时,与1相加会超出整型数的表示范围;而且当求INT_MAX的均方根时,在判断if(x >= ans*ans)时一定会出现ans*ans的结果溢出,可以改为if(x / ans >= ans)。
    3. 要对范围溢出的错误敏感:INT_MIN = -2147483648 INT_MAX = 2147483647
    4. 研究一下牛顿法

    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?

    Note: Given n will be a positive integer.

    解题思路:

    1. 到第n个台阶的方法数等于到第n-1个台阶数的方法数加到第n-2个台阶数的方法数。依次递推。

    刷题记录:

    1. 第一次没有自己的思路 NO BUG FREE

    71. Simplify Path

    Given an absolute path for a file (Unix-style), simplify it.

    For example,
    path = "/home/", => "/home"
    path = "/a/./b/../../c/", => "/c"

     
    解题思路:
    1. 将string类型变量转化为stringsteam流后使用getline()函数读取会非常方便。用vector来实现栈空间特性。
    2. for(auto str:substring) ans += "/"+str;可以实现对vector的自动遍历。

     刷题记录:

    1. 参考答案,NO BUG FREE,需重写一遍。

     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

     
     解题思路:
    1. 用动态规划的办法,设p[i][j]为字符串word1[0~i-1]转化为字符串word2[0~j-1]所需的操作数。那么:如果当前位置的字符相同,即word1[i]=word2[j],则最小操作数p[i][j]=p[i-1][j-1]。如果当前操作数不同,那么可能出现替换,增加和删除三种操作,分别所需的操作次数为p[i-1][j-1]+1,p[i][j-1]+1和p[i-1][j]+1次,取其最小值即可。依次循环遍历,可解。

    刷题记录:

    1. 第一遍看了答案才有动态规划的思路,NO BUG FREE,需重写一遍。

    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.

    解题思路:

    1. 当某个元素为0时,需要把元素所在行和列的所有元素都化为0。因此第一次遍历数组需要确定哪些行和列需要转化为全0,把状态存储在数组的每一行和每一列的第一个元素表示;第二次遍历数组,根据前面存储的状态对数组元素进行更改,需要注意此时需要从后往前遍历数组,因为从前往后的话对第一行和第一列的更改会影响它们记录的状态。

     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. 相当于在二维数组的二分法查找应用,只要能找到元素在二维数组中的对应位置即可。

    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.

     
    解题思路:
    1. 分别从数组的头部和尾部向中间遍历,用flag1来表示从头遍历时1的位置,由于1要处于中部,所以每当遇到0时就与flag1对应位置上的数相交换;flag2有对应的含义。从头遍历到2时停止,从尾遍历到0时停止,相交换即可,不改变i和j的值,使得下一次大循环时,会将0或2 与1相交换。

    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 empty string "".

    If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

    解题思路:

    1. 从前往后遍历,用map结构来存储当前包含的字符以及字符个数,设定start和end标签即可,找到每次至少包含所有目标字符串中字符的最短字符串,与最短串进行比较即可。
    2. string.size()的返回值类型为unsigned int,当将其直接与类似-1的有符号值进行比较时,会自动将-1转化为unsigned int进行判断,导致出错。

    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],
    ]

    解题思路:

    1. 用DFS查找来搜寻所有可能的组合,定义循环的下界和上界,依次向组合向量中加入即可。

    78. Subsets

    Given a set of distinct integers, nums, return all possible subsets.

    Note: The solution set must not contain duplicate subsets.

    For example,
    If nums = [1,2,3], a solution is:

    [
      [3],
      [1],
      [2],
      [1,2,3],
      [1,3],
      [2,3],
      [1,2],
      []
    ]
    

    解题思路:

    1. 从第一个元素开始循环,前面已经存在过的所有组合均复制一遍,前一半不加入当前元素,复制的新的一半加入当前元素。直到循环结束,最后得到的向量包含组合个数应为2^n。

    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 =

    [
      ['A','B','C','E'],
      ['S','F','C','S'],
      ['A','D','E','E']
    ]
    

    word = "ABCCED", -> returns true,
    word = "SEE", -> returns true,
    word = "ABCB", -> returns false.

     
    解题思路:
    1. 遍历整个字符数组,从数组中找到与目标字符串首字符相同的字符位置,作为递归调用的起点。每次调用后有四个方向分别是上、下、左、右去寻找下一个字符,找到后,把下一个字符的位置作为起点,而且将其字符改为' ',避免再次使用,调用结束后再改回来。
    2. string a("adwafs");a.substr(1);可自动取string a从a[1]到整个字符串尾部的子字符串。

    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 nums = [1,1,1,2,2,3],

    Your function should return length = 5, with the first five elements of nums being 1122 and 3. It doesn't matter what you leave beyond the new length.

    解题思路:
    1. 从前往后遍历数组,只要当前位置上的数大于前移两个位置上的数,即nums[i] > nums[i-2],说明当前数不是相同的第三个数,因此可以存入数组中。

    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?

    Suppose an array sorted in ascending order 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).

    Write a function to determine if a given target is in the array.

    The array may contain duplicates.

     
    解题思路:
    1. 基本思路与之前的在偏移数组中查找目标数的方法是一致的,但是存在的问题是当nums[mid]=nums[low]时,无法判断mid点是处于前一部分还是后一部分,因此选择将low++的办法,最坏情况下的时间复杂度为O(n)。

    刷题记录:

    1. 刚开始时总想着有没有好的办法避免出现时间复杂度为O(n)的情况,最后看的答案发现没有。需重写一遍,NO BUG FREE

    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.

    解题思路:
    1. 从前往后遍历链表,如果当前结点的值与下一结点的值相同,为重复数,继续往后循环到第一个不同的数;如果当前结点的下一结点为空,则只存在单独的此数,加入链表中。
    2. 注意最后需要把尾结点的next指针置为NULL。

    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.

    解题思路:
    1. 从前往后遍历链表,下一结点的val值与当前结点的val值相同时,p = p -> next,移动指针到下一结点;当遇到与之前结点不同的值时停止循环,向返回链表中加入该结点。
    2. 同样注意最后要让尾结点的next指向NULL。

    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 heights = [2,1,5,6,2,3],
    return 10.

     
    解题思路:
    1. 最大面积的矩形一定是以某个小矩形的高度为上界的,因此算法的核心在于找到以每个小矩形的高度为高的左边界和右边界,从而能求出最大宽度。最优算法的时间复杂度为O(n),定义一个向量用来存储从低到高的矩形对应位置,如果当前矩形的高度大于等于向量最后一个元素矩形的高度,那么直接把当前矩形的index加入向量中;如果当前矩形的高度小于前一矩形的高度,那么当前矩形的位置就是对应前一矩形的右边界,存储前一矩形的高度后将其pop出向量,找到再往前比其低的矩形,即为左边界,这样就可以算出以该矩形为高度的最大矩形的面积。最后再把后一矩形的index加入向量中。

    刷题记录:

    1. 自己没有很好的思路,看到答案后仍然难以理解,虽然最后理解并写出来,需要重写一遍,NO BUG FREE

    85. Maximal Rectangle

    Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

    For example, given the following matrix:

    1 0 1 0 0
    1 0 1 1 1
    1 1 1 1 1
    1 0 0 1 0
    

    Return 6.

    解题思路:

    1. 此题最好的思路是基于上题的解题方法,大循环对每行进行遍历,每行内部构造一列矩形高度的矩形,按照上题的思路求解最大矩形即可。当某点为'1'此位置矩形的高度加1;当某点为'0'时此矩形的高度重置为0。

    刷题记录:

    1. 独立没有思路,NO BUG FREE

    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.

    解题思路:

    1. 最好的方法是建立两个链表,第一个存储小于目标值的所有结点,第二个存储大于目标值的所有结点。最后记得将两个链表合并,而且将第二个链表尾结点的指向置NULL。

    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. 本题采用最暴力最简单的方式,分别假设字符串用二叉树表示时是从第一个位置开始分叉的,到最后一个位置的所有情况,讨论非叶子结点是否交换混淆的每种情况。用递归的方式讨论代码量相对简单。

    刷题记录:

    1. 看了标准答案后才有思路,NO BUG FREE

    88. Merge Sorted Array

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

    Note:
    You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.

    解题思路:

    1. 此题题目的意思就是不再在数组中增添额外的空间,将两个数组合并存放在数组1的空间中,所以不要用insert函数。直接从后往前遍历(由于多余的空间是在数组的后方),将对应位置大的数优先存放在数组的尾部即可。

    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.

     
    解题思路:
    1. n=3时的结果可以根据n=2的结果来得到,是一种镜像的关系,将n=2的结果加上2^2反向添加入向量中即可。

    90. Subsets II

    Given a collection of integers that might contain duplicates, nums, return all possible subsets.

    Note: The solution set must not contain duplicate subsets.

    For example,
    If nums = [1,2,2], a solution is:

    [
      [2],
      [1],
      [1,2,2],
      [2,2],
      [1,2],
      []
    ]
    

    解题思路:

    1. 递归调用求不同的子集,方法是当前元素为递归头元素或者与前一元素不同时时,加入向量中。

    刷题过程:

    1. 思路不是很清晰,最好重写一遍,NO BUG FREE

    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.

    解题思路:
    1. 此题采用动态规划的办法,如果当前位置上的字符为'0',那么一定得和前面的字符组合起来,将前一个字符所有字符解码方法的数量置0。之后判断当前位置上的字符能否与前一个字符组合,如果能,那么当前位置的解码数量等于r1+r2;如果不能,解码数量为r1。一直循环到最后一个位置。

    刷题记录:

    1. 刚开始使用递归调用的方法会导致时间超出,改换动态规划的方法。测试集中间可能会出现单独的'0'导致返回结果为0。NO BUG FREE,刚开始思路不明确,最好重写一遍。 

    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->NULLm = 2 and n = 4,

    return 1->4->3->2->5->NULL.

    Note:
    Given mn satisfy the following condition:
    1 ≤ m ≤ n ≤ length of list.

     
    解题思路:
    1. 为了使代码在不同情况下都能运行,具有统一性,创建一个空的头结点,使其指向原本的头指针。一般用dummy表示,有时候不一定要用指针来表示链表中结点的位置,变量名也可以。

    93. Restore IP Addresses

    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)

    解题思路:

    1. 此题可以用递归的方法解,也可以用循环嵌套的方式解,先找出每个IP数字位数为1到3位的组合,再判断每位IP位数是否合格来觉得是否加入最终队列中的方式。

    94. Binary Tree Inorder Traversal

    Given a binary tree, return the inorder traversal of its nodes' values.

    For example:
    Given binary tree [1,null,2,3],

       1
        
         2
        /
       3
    

    return [1,3,2].

    Note: Recursive solution is trivial, could you do it iteratively?

    解题思路:

    1. 不用递归用迭代的方法解题,首先循环找到最左的结点,将当前结点的值加入遍历结果向量中,然后指针指向当前结点的右指针,重复进行中序遍历操作。

    刷题记录:

    1. 很经典的二叉树中序遍历问题,最好重新写一遍,NO BUG FREE

    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
    

    解题思路:

    1. 此题可以转化为一个DP问题,n=2时,相当于以两个不同的数字为根结点时的1个元素二叉树排列问题;n=3时,相当于以3个不同的结点为根结点时,各自两边二叉树的组合。循环叠加就好。

    刷题记录:

    1. 求不同二叉树的数量问题,很经典

    95. Unique Binary Search Trees II

    Given an integer 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

    解题思路:

    1. 递归函数返回指定元素数构成的不同结构的二叉树的根结点向量,要注意如果用的是值传递方式,可以将返回值(也就是根节点)保存下来,但是在函数内部定义的所有其他子结点所占的内存都会随着函数运行周期的结束而释放掉,无法通过根结点的左右指针继续访问。所以想要使定义的结点一直保留的话,需要用指针new的方式。
    2. 要注意向量可以push_back(NULL),即空元素,会导致向量的长度加1,不再为空。

    刷题记录:

    1. 很经典的生成二叉树不同结构的问题,需要完全掌握。

    97. Interleaving String

    Given s1s2s3, 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.

     
    解题思路:
    1. 用递归调用的方法会使时间超出限制,使用动态规划的方法可以很好的解决这个问题。定义一个bool类型的二维数组,p[i][j]表示s1的前i个字符和s2的前j个字符是否能穿插表示s3的前i+j个字符;p[i][j]等于p[i-1][j]和s1的第i个字符是否与s3的第i+j-1个字符相同的逻辑与,再并上p[i][j-1]和s2的第j个字符是否与s3的第i+j-1个字符相等的逻辑与。
    2. 循环结束后返回向量p[len1][len2]。

    刷题记录:

    1. 动态规划很经典的问题,刚开始自己完成的是递归函数,知道看到答案的DP提示才有了自己的思路。

    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.

    Example 1:

        2
       / 
      1   3
    

    Binary tree [2,1,3], return true.

    Example 2:

        1
       / 
      2   3
    

    Binary tree [1,2,3], return false.

    解题思路:

    1. 用中序遍历的方法辩论整棵二叉排序树,如果为增序序列,则会有效,如果不是,则不是有效的二叉排序树。

    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?

     
    解题思路:
    1. 简单的方法是使用递归中序遍历的方法,当出现当前元素的值小于前一个位置的值时,为出现交换的位置。找到交换的两个元素之后,将其val交换即可,不用交换其指针。
    2. 要注意的一点时,在使用任何变量时一定要对变量进行初始化,比如说在定义了一个指针int *p后,用if(p==NULL)会出现错误,应该在定义指针的时候将指针初始化为空指针:int *p=NULL;
    3. 不管是用递归还是栈的方式实现中序遍历,空间复杂度都为O(n),因为递归函数会自动开启栈空间。Morris Traversal是一种空间复杂度仅为O(1)的遍历方法。http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html

    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.

    解题思路:

    1. 比较两个数结构和数字是否相同,比较根结点的值是否相同,然后递归调用原函数比较其左子树和右子树的结构是否相同,如果相同,返回True。

    101. Symmetric Tree

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

    For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

        1
       / 
      2   2
     /  / 
    3  4 4  3
    

    But the following [1,2,2,null,3,null,3] is not:

        1
       / 
      2   2
          
       3    3
    

    Note:
    Bonus points if you could solve it both recursively and iteratively.

     
    解题思路:
    1. 此题为判断一个数是否为镜像树的问题,除了根结点,都是比较非叶子结点的左子结点是否与对应结点的右子结点相同;以及比较非叶子结点的右子结点是否与对应结点的左子结点相同。因此可以采用递归的方法去写,也可以采用迭代的方法。
    2. 递归和迭代的区别在于递归是通过函数调用函数自身来实现代码的重复执行,而迭代是在函数内通过循环来实现代码段的重复执行。两者都需要使用栈空间,差异在于递归会自动调用栈,而迭代需要手动定义和使用栈空间。

    102. Binary Tree Level Order Traversal

    Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).

    For example:
    Given binary tree [3,9,20,null,null,15,7],

        3
       / 
      9  20
        /  
       15   7
    

    return its level order traversal as:

    [
      [3],
      [9,20],
      [15,7]
    ]
    

    解题思路:

    1. 层序遍历最基本的思路就是利用队列的结构,访问当前层的所有结点,将当前层的结点的左子结点和右子结点依次加入队列中,在下一次循环中进行访问。
    2. 队列可以用STL库queue来实现,queue.front()访问队列头元素,queue.back()访问队列尾元素,queue.pop()将队列头元素出队列,还包括empty(),size()等基本函数。在不记得queue时,也可以用vector来模拟队列,此时要记录代表向量中开始和结尾的位置。
    3. for(int i = 0;i < queue.size();i++) 在每次循环进行循环条件的比较时,queue.size()函数都会重新计算,所以要注意这个问题,如果函数内部对queue的长度进行更改,可能循环就不会按理想中的情况进行。

    103. Binary Tree Zigzag Level Order Traversal

    Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

    For example:
    Given binary tree [3,9,20,null,null,15,7],

        3
       / 
      9  20
        /  
       15   7
    

    return its zigzag level order traversal as:

    [
      [3],
      [20,9],
      [15,7]
    ]
    

    解题思路:

    1. 借助队列的思路,把下一层的结点存储在一个向量中,当把当前向量遍历完之后再将下一个向量赋值给当前向量。向量间的相互赋值有三种:1、通过等号直接赋值,一般不提倡。2、使用assign函数赋值,v2.assign(v1.begin(),v1.end())。3、v2.clear()后使用for循环赋值。
    2. 有的时候要注意转换思路,结点的顺序不变,在存储值的时候存入相应的位置就可以;比改变结点的顺序,顺序存储的方法简单一些。

    104. Maximum Depth of Binary Tree

    Given a binary tree, find its maximum depth.

    The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

    解题思路:

    1. 用队列的方式,记录下循环遍历队列的次数,即为二叉树的最大深度。或者该题也可以用直接递归的方式去做,如果根结点不为空,那么最大深度为1+左右子树的最大深度。

    105. Construct Binary Tree from Preorder and Inorder Traversal

    Given preorder and inorder traversal of a tree, construct the binary tree.

    Note:
    You may assume that duplicates do not exist in the tree.

     
    解题思路:
    1. 首先找到根结点,再找到其左子树和右子树的前序遍历和中序遍历,用递归的方式返回其左右子树的根结点即可。
    2. 用迭代的方法写一遍,循环访问前序遍历,先比较当前中序遍历位置元素是否与栈顶元素相同,如果相同代表着此栈顶元素的左子树为NULL或者已经构造访问完,此时将栈顶元素出栈,并将flag置1,表示下一入栈元素写为该元素的右指针。

    106. Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree.

    Note:
    You may assume that duplicates do not exist in the tree.

    解题思路:
    1. 与上题整体思路相同,采用递归和迭代两种方式解题。

    107. Binary Tree Level Order Traversal II

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).

    For example:
    Given binary tree [3,9,20,null,null,15,7],

        3
       / 
      9  20
        /  
       15   7
    

    return its bottom-up level order traversal as:

    [
      [15,7],
      [9,20],
      [3]
    ]
    

    解题思路:

    1. 与层序遍历的方法相同,最后将向量反向输出,可以选择return vector<vector<int> > (res.rbegin(), res.rend())。(其中res也是一个vector<vector<int> >)

    108. Convert Sorted Array to Binary Search Tree

    Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

    解题思路:

    1. 每次取中间的数作为根结点,小于它和大于它的数分别作为其左子树和右子树。递归调用即可。
    2. 二叉平衡树的条件:1、它的左右子树都是平衡二叉树;2、它的左、右子树的高度之差的绝对值小于1。

    109. Convert Sorted List to Binary Search Tree

    Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.

    解题思路:

    1. 此题可以用简单递归方式,即每次循环都对链表进行遍历,根据记录的头指针和尾指针找到中间结点作为根结点。
    2. 上述方法时间复杂度较高,实际上在得到链表长度后,可以定义一个私有变量node,用DFS的思路进行递归,先找到左子树返回结点,再定义当前结点,之后再将返回当前结点右指针。这样结点定义的顺序就与链表从小到大的顺序相同,每次定义新结点后,将共同维护的指针指向next即可。

    刷题记录:

    1. DFS的思路很特别,用巧妙的方式降低了时间复杂度,需重写一遍

    110. Balanced Binary Tree

    Given a binary tree, determine if it is height-balanced.

    For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

    解题思路:

    1. 判断一棵树是否为平衡二叉树首先要判断其左子树和右子树的高度差是否小于1,其次需要判断左子树和右子树是否分别为二叉平衡树。如果从上到下进行处理的话,在判断子树是否为二叉平衡树的过程中会出现大量的重复遍历,导致时间复杂度很高。
    2. 相反,如果从底部往上遍历,先判断子树是否为二叉平衡树,再判断高度差。不仅在子树不为二叉平衡树时可以第一时间返回false,而且子树的高度运算结果可以得到保留给上一层树判断使用,避免了重复求高度的过程。

    刷题记录:

    1. 从底向上的过程很奇妙,需重写一遍

    111. Minimum Depth of Binary Tree

    Given a binary tree, find its minimum depth.

    The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

    解题思路:

    1. 用队列的方式访问树的结点,记录层数,当某个结点的左右子树结点都为NULL时说明为叶子结点,此时break,返回层数即可。
    2. 用递归调用的方式也可以解这个题,但是时间损耗上偏高,深度优先遍历。

    112. Path Sum

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

    For example:
    Given the below binary tree and sum = 22,

                  5
                 / 
                4   8
               /   / 
              11  13  4
             /        
            7    2      1
    

    return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

    解题思路:

    1. 递归调用原函数即可,注意题目要求必须是从根结点到叶子结点,所以终点结点的左右子树一定都为NULL。

    113. Path Sum II

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

    For example:
    Given the below binary tree and sum = 22,

                  5
                 / 
                4   8
               /   / 
              11  13  4
             /      / 
            7    2  5   1
    

    return

    [
       [5,4,11,2],
       [5,8,4,5]
    ]
    

    解题思路:

    1. 采用递归调用的方式,当当前结点的值与所需sum值相同,且左右子树结点都为NULL即为叶子结点时,为一条正确的路线。

    114. Flatten Binary Tree to Linked List

    Given a binary tree, flatten it to a linked list in-place.

    For example,
    Given

             1
            / 
           2   5
          /    
         3   4   6
    

    The flattened tree should look like:

       1
        
         2
          
           3
            
             4
              
               5
                
                 6
    

     

    解题思路:

    1. 递归调用,链表的顺序与前序遍历相同。

    115. Distinct Subsequences

    Given a string S and a string T, count the number of distinct subsequences of T in S.

    A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).

    Here is an example:
    S = "rabbbit", T = "rabbit"

    Return 3.

    解题思路:
    1. 递归写起来简单,但是算法执行复杂度特别高(比如字符的比对问题)时,一定要想到动态规划的方法。直接根据两个字符串的长度,建立一个二维数组,然后再去找对应元素之间的关系。
    2. 此题中,设i为原字符串中的位置,j为目标字符串中的位置,则num[i][j]代表的是在0~i的字符串中0~j的字符串出现的次数。显然num[i][j] = s[i]==t[j] ? num[i-1][j-1]+num[i-1][j] : num[i-1][j]。

    刷题记录:

    1. 总是无法自己确信动态规划的方法,需要更加自信一点,重写一遍

    116. Populating Next Right Pointers in Each Node

    Given a binary tree

        struct TreeLinkNode {
          TreeLinkNode *left;
          TreeLinkNode *right;
          TreeLinkNode *next;
        }
    

    Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

    Initially, all next pointers are set to NULL.

    Note:

    • You may only use constant extra space.
    • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

    For example,
    Given the following perfect binary tree,

             1
           /  
          2    3
         /   / 
        4  5  6  7
    

    After calling your function, the tree should look like:

             1 -> NULL
           /  
          2 -> 3 -> NULL
         /   / 
        4->5->6->7 -> NULL
    

    解题思路:

    1. 利用两个指针可以循环完成这些操作,用root指针始终存储每一行最左边结点的位置,用指针p循环右移,来给其子结点的指针赋值。

    117. Populating Next Right Pointers in Each Node II

    Follow up for problem "Populating Next Right Pointers in Each Node".

    What if the given tree could be any binary tree? Would your previous solution still work?

    Note:

    • You may only use constant extra space.

    For example,
    Given the following binary tree,

             1
           /  
          2    3
         /     
        4   5    7
    

    After calling your function, the tree should look like:

             1 -> NULL
           /  
          2 -> 3 -> NULL
         /     
        4-> 5 -> 7 -> NULL
    

    解题思路:

    1. 当二叉树变得任意时就需要定义三个指针,一个prev存储本层的结点位置,一个root存储下一层开始的位置,一个p用来遍历下一层的结点为工作指针。通过root指针是否为空来判断二叉树是否遍历完,在判断root是否已经赋值时不一定非要定义一个bool型的flag来标识,直接if (root==NULL)即可。

    118. Pascal's Triangle

    Given numRows, generate the first numRows of Pascal's triangle.

    For example, given numRows = 5,
    Return

    [
         [1],
        [1,1],
       [1,2,1],
      [1,3,3,1],
     [1,4,6,4,1]
    ]
    
    解题思路:
    1. 观察杨辉三角的特征,循环依次加入向量即可。下一层的中间元素是上一层两边元素之和。

    119. Pascal's Triangle II

    Given an index k, return the kth row of the Pascal's triangle.

    For example, given k = 3,
    Return [1,3,3,1].

    Note:
    Could you optimize your algorithm to use only O(k) extra space?

    解题思路:
    1. 当所能使用的空间只有O(k)时,要注意每行求得的元素在向量中的排列位置,从后往前计算当前行的元素,就不会因为存储结果而影响之后的计算。

    120. Triangle

    Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

    For example, given the following triangle

    [
         [2],
        [3,4],
       [6,5,7],
      [4,1,8,3]
    ]
    

    The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

    Note:
    Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

     
    解题思路:
    1. 利用DP的思想去做,到本层某个结点的最短路径等于到其上一层两边结点中的较短路径加上该结点本身的值,一直循环到最后一层即可得到到每个结点的最短路径,取最短为所求。
    2. 同样,针对杨辉三角问题,在求和时,逆序存储会得到很好的效果。

    121. Best Time to Buy and Sell Stock

    Say you have an array for which the ith element is the price of a given stock on day i.

    If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

    Example 1:

    Input: [7, 1, 5, 3, 6, 4]
    Output: 5
    
    max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)
    

    Example 2:

    Input: [7, 6, 4, 3, 1]
    Output: 0
    
    In this case, no transaction is done, i.e. max profit = 0.
    

    解题思路:

    1. 此题转化为一个相邻数列差,求和最大的问题。

    122. Best Time to Buy and Sell Stock II

    Say you have an array for which the ith element is the price of a given stock on day i.

    Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

    解题思路:
    1. 与上题类似,首先求出相邻天售卖股票的收益差,当出现连续盈利时,累加起来;当出现亏损时,表明股票应提前出手,将当前盈利加入到最后的盈利和中去。

    123. Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i.

    Design an algorithm to find the maximum profit. You may complete at most two transactions.

    Note:
    You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

    解题思路:
    1. 此题为一个动态规划问题,通过求不同交易次数,在不同prices节点上的最大收益来得到最终结果。

    刷题记录:

    1. 算法很奇妙,需要重新做一遍

    124. Binary Tree Maximum Path Sum

    Given a binary tree, find the maximum path sum.

    For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.

    For example:
    Given the below binary tree,

           1
          / 
         2   3
    

    Return 6.

    解题思路:
    1. 定义一个新的函数,用来返回到根结点的单条路径的最大长度。在函数体中递归调用自身,返回到左子树根节点和右子树根结点的最大长度,将两者和根节点相加与maxSum作比较;并将两者中的较大者与根结点相加的结果作为上一层结点的最长路径返回。当需要一个函数共同来维护和改变一个变量时,除了将变量以地址调用的形式写入函数参数里,也可以定义为类的private变量。

    刷题记录:

    1. 思路很奇妙,写法很简单,NO BUG FREE

    125. Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

    For example,
    "A man, a plan, a canal: Panama" is a palindrome.
    "race a car" is not a palindrome.

    Note:
    Have you consider that the string might be empty? This is a good question to ask during an interview.

    For the purpose of this problem, we define empty string as valid palindrome.

     
    解题思路:
    1. 设定两个index,分别从前往后和从后往前遍历字符串,当字符是字母或者数字时停止,进行比较。如果相同,则i++,j--进行下一次循环,反之返回false。
    2. 在这里注意int tolower(int c);函数的用法,函数作用是遇到大写字母,返回其对应小写字母的ASCII码;遇到其他字符不变返回即可。

    127. Word Ladder

    Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

    1. Only one letter can be changed at a time.
    2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

    For example,

    Given:
    beginWord = "hit"
    endWord = "cog"
    wordList = ["hot","dot","dog","lot","log","cog"]

    As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
    return its length 5.

    Note:

    • Return 0 if there is no such transformation sequence.
    • All words have the same length.
    • All words contain only lowercase alphabetic characters.
    • You may assume no duplicates in the word list.
    • You may assume beginWord and endWord are non-empty and are not the same.
     
    解题思路:
    1. 这是一个典型的BFS问题,每一层往下查找当前层的词语经过一次字符变换能转变成的所有词语。可以从beginword出发,定义一个队列存储当前层能转换的词语,一个向量存储对应的词语是否已经能转换到。如果能访问endword,则返回当前层数,即为最短路径;如果队列为空,则不能访问到。

    126. Word Ladder II

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

    1. Only one letter can be changed at a time
    2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

    For example,

    Given:
    beginWord = "hit"
    endWord = "cog"
    wordList = ["hot","dot","dog","lot","log","cog"]

    Return

      [
        ["hit","hot","dot","dog","cog"],
        ["hit","hot","lot","log","cog"]
      ]
    

    Note:

    • Return an empty list if there is no such transformation sequence.
    • All words have the same length.
    • All words contain only lowercase alphabetic characters.
    • You may assume no duplicates in the word list.
    • You may assume beginWord and endWord are non-empty and are not the same.
     
    解题思路:
    1. 首先需要和上题一样存储下每层能到达的结点(也就是能转换成的单词),其次需要记录下所有转换成该单词的方法(路径)。由于转换成同一单词,可能经由多种方法,所以对每个未转换到的点,需要访问所有的当前结点,探寻可能性,重复遍历选择vector存储。
    2. 存储结构vector<int>:BFS当前层能转换成的单词index;vector<int>:对应index结点是否已经能转换得到,1表示能,0表示不能;map<int,vector<vector<string>>>存储到达对应index结点的转换方法。
    3. 在寻找是否存在与当前word只相差一个character的时候,一种选择是将其与剩下的每个word进行遍历比较,如果单词数为n,单词长度为l,时间复杂度为O(nl);另一种选择是对当前单词的每个位置进行26个字母的改写循环,即把每个单独的位置改写成其他26个字符,再比较得到的新单词在wordList中是否存在,这就要求单词以键值的形式hash存储,时间复杂度为O(26l)。

    刷题记录:

    1. 在处理复杂的存储结构时,思维有点混乱,下次应该理清楚再写。NO BUG FREE

    128. Longest Consecutive Sequence

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

    For example,
    Given [100, 4, 200, 1, 3, 2],
    The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

    Your algorithm should run in O(n) complexity.

     
    解题思路:
    1. 题目要求时间复杂度为O(n),因此需要在遍历一遍向量后便得出结果,在每次访问元素时都需要用合适的存储结构保留下当前信息。访问元素时间复杂度为O(1)的结构是map。
    2. 用map<int,int> len存储包含当前整数的连续数列的最长长度。遍历到元素nums[i]时,先判断nums[i]-1在map中是否存在,如果存在,left=len[nums[i]-1],不存在left=0;再判断nums[i]+1在map中是否存在,如果存在,right=len[nums[i]+1],否则为0。那么当前元素的len[nums[i]]=left+right+1。注意同时还有修改最左端nums[i]-left和最右端nums[i]+right对应的数列长度。

    刷题记录:

    1. 第一遍做的时候存储结构有点多余,对于每一个元素,使用pair结构存储其最左端元素和最右端元素的方式。更好的方式只需要存储数列长度就好。

    129. Sum Root to Leaf Numbers

    Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

    An example is the root-to-leaf path 1->2->3 which represents the number 123.

    Find the total sum of all root-to-leaf numbers.

    For example,

        1
       / 
      2   3
    

    The root-to-leaf path 1->2 represents the number 12.
    The root-to-leaf path 1->3 represents the number 13.

    Return the sum = 12 + 13 = 25.

    解题思路:
    1. 大部分与二叉树有关的题都可以用递归的方式去解决。上层树结构累积的值乘以10加上当前结点的值为到此结点的累计值。注意叶子结点的判断条件一定是root->left==NULL && root->right==NULL!

    130. Surrounded Regions

    Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

    A region is captured by flipping all 'O's into 'X's in that surrounded region.

    For example,

    X X X X
    X O O X
    X X O X
    X O X X
    

    After running your function, the board should be:

    X X X X
    X X X X
    X X X X
    X O X X
    

    解题思路:

    1. 没有被包围的'O'指的是在'X'内部的,即没有与四条边界上的'O'连通的。因此可以从四边上的'O'出发,递归寻找所有连通的未被包围的'O',并且标记为'1',避免重复查找,多用递归的方法(其实递归的方式和栈的方式使用的内存空间是一样的)。
    2. 本题中出现了一个问题,就是当递归条件是i-1>=0和j-1>=0时,在特殊的board情况下,会一次递归完所有的'O',导致栈空间占用过大而溢出,出现time error错误。

    131. Palindrome Partitioning

    Given a string s, partition s such that every substring of the partition is a palindrome.

    Return all possible palindrome partitioning of s.

    For example, given s = "aab",
    Return

    [
      ["aa","b"],
      ["a","a","b"]
    ]
    

    解题思路:

    1. 本题需要寻找所有可能的回文字符串划分方法,因此采用循环+递归的方式。循环查找从当前位置开始,所有可能的不同长度的回文字符串,加入向量中,再递归查找剩下的字符串中的分割方法。
    2. 定义一个函数用来判断字符串是否为回文字符串,将返回结果以地址传递的方式作为递归函数的参数。

    132. Palindrome Partitioning II

    Given a string s, partition s such that every substring of the partition is a palindrome.

    Return the minimum cuts needed for a palindrome partitioning of s.

    For example, given s = "aab",
    Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

    解题思路:
    1. 字符串问题,如果想知道字符串任意位置到另一任意位置的子串情况,就构造一个2D的数组,每一维的大小等于字符串的长度。
    2. 用bool二维数组ispalin[i][j]表示string(i..j)是否为一个回文字符串,其条件为:1 string[i] = string[j];2 ispalin[i+1][j-1]为true,为一个回文字符串。如果string(i..j)是一个回文字符串,那么从i到字符串的末尾的最小分配就为1+string[j+1]到末尾的最小分配。
    3. 动态规划之间的相互关系决定了从字符串末尾往前循环较为方便。要保证动态规划中判断所需要的信息已经计算出来。

    刷提记录:

    1. 自己做的时候采用递归的方法,果不其然会出现TLE的问题,动态规划的思路需要根深蒂固。NO BUG FREE.

    133. Clone Graph

    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.


    OJ's undirected graph serialization:

    Nodes are labeled uniquely.

    We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.

    As an example, consider the serialized graph {0,1,2#1,2#2,2}.

    The graph has a total of three nodes, and therefore contains three parts as separated by #.

    1. First node is labeled as 0. Connect node 0 to both nodes 1 and 2.
    2. Second node is labeled as 1. Connect node 1 to node 2.
    3. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.

    Visually, the graph looks like the following:

           1
          / 
         /   
        0 --- 2
             / 
             \_/
    

    解题思路:

    1. 图结构进行克隆的意思是重新申请同样的多的结点空间,并使内部成员变量与原图相同。定义一个map<int,GraphNode*>结构用来存储对应int的结点是否已经申请,如果已经定义,直接把地址加入到结点的向量中;如果没有定义则递归调用原函数,返回新结点的地址。切忌不经过map的判断直接进行递归,会导致重复申请相同值结点的问题。

    134. Gas Station

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

    You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

    Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

    Note:
    The solution is guaranteed to be unique.

    解题思路:

    1. 加油站问题用动态规划的方式,三个变量即可,start存储开始的位置,为0~N-1;prev为前面行驶所缺的汽油量,为负;cur为当前行程所富余的汽油量。当cur+gas[i]-cost[i]为正时,继续循环,但是当为负时,说明前面经过的所有站都不可能是起点站,因为只有当前面汽油的富余量为正时,才会继续累积。如果从中间的站点出发,会导致富余的汽油量更少,此时直接将start改写为i+1,并用prev更新前面亏损的总汽油量。
    2. 遍历一次所有站点,得到起始位置到最后的富余量和之前的缺少量,如果富余量大于等于缺少量,则可以完成行程返回start;反之返回-1。

    135. Candy

    There are N children standing in a line. Each child is assigned a rating value.

    You are giving candies to these children subjected to the following requirements:

    • Each child must have at least one candy.
    • Children with a higher rating get more candies than their neighbors.

    What is the minimum candies you must give?

    解题思路:

    1. 两遍循环可以轻松的解决这个问题,正向循环时,如果当前位置i的ratings大于位置i-1的ratings时,获得的糖果数为前面的糖果数加1;反向循环时,如果当前位置i的ratings大于位置i+1的ratings时,获得的糖果数为后面的糖果数加1和其原本糖果数的最大值(用来处理增序列和减序列的交界值)。

    136. Single Number

    Given an array of integers, every element appears twice except for one. Find that single one.

    Note:
    Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

    解题思路:
    1. 此题利用的是按位异或(^)运算符的使用,两个完全相同的数按位异或的结果为0,与0异或的结果为数字本身。因此将数组中的所有数一块异或,所有成对的相同整数异或结果为0,剩下的单一整数与0异或结果为其本身。

    137. Single Number II

    Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

    Note:
    Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

    解题思路:
    1. 此题可以推广到一个向量中每个数出现了k次,只有一个数出现了p次,找出这个数的问题。问题的突破口在于把所有的数看作是一个二进制的数列,统计每个bit上'1'出现的次数,每当出现k次,就将统计数置0,因为对于同一个数而言,如果某个位置为'1',那么遍历完向量,当前位置的1肯定加入了k次,不是属于我们寻找的数的'1'。
    2. 假如2^(m-1)<k<=2^m,那么我们就需要m个整数来统计每个位置出现的'1',这m个整数同一位置的数组成的二进制数便为当前位置的'1'的数量。所以高位加1的条件是,当前数在当前位置上有'1',而且低位均为'1'。
    3. 用mask变量来清除重复k次的'1',如果是3次,即'11'时清0,mask=~(x2&x1),如果是4次,'100'时清0,mask=~(x3&~x2&x1)。再用mask与x1,x2位置&。
    4. 最后输出哪个结果是,要观察,当目标数的'1'出现p次时,哪些高位上会出现'1',就输出那些数。

    刷题记录:

    1. 算法的思路很奇妙,主要涉及bit变换和想法的转变,NO BUG FREE

    138. Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

    Return a deep copy of the list.

    刷题记录:

    1. 该题的难点在于不同的结点可能出现重复的标签,因此需要用某种方式记录下random指向的结点到底是哪个结点。有三种方法:1 自己的思路:针对初始的链表copy时,将new的新结点存储在向量中,并改变原始结点的label成链表顺序的标签。因此,通过第二次遍历时访问random结点的label就可以知道具体指的是向量中哪一个结点。2 最优的思路:在copy链表时,将新结点改写为对应原结点的next,那么原始结点所指向random结点的next结点就是新结点对应的random结点,新结点的random写入完成之后,再将两个链表分开。 3 构建一个map,键和value值都是结点地址,用旧的结点地址确定新的结点地址。

    139. Word Break

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words.

    For example, given
    s = "leetcode",
    dict = ["leet", "code"].

    Return true because "leetcode" can be segmented as "leet code".

    UPDATE (2017/1/4):
    The wordDict parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.

    解题思路:

    1. 使用动态规划的方法,定义一个bool类型的向量用来存储从s[0~i]是否能划分为词典中的组合,当前位置j对应的bool值ifbreak[j]=ifbreak[i] && 子字符串s[i+1~j]在字典中是否存在。因此到后一个位置的子字符串是否能划分为词典中word的组合可以依赖于之前所使用到的信息,使得算法更快捷。

    刷题记录:

    1. 自己的做的时候只会使用递归的方法,特别low和耗时,最后果不其然出现TLE的问题,以后遇到字符串问题优先考虑动态规划。NO BUG FREE.

    140. Word Break II

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. You may assume the dictionary does not contain duplicate words.

    Return all such possible sentences.

    For example, given
    s = "catsanddog",
    dict = ["cat", "cats", "and", "sand", "dog"].

    A solution is ["cats and dog", "cat sand dog"].

    UPDATE (2017/1/4):
    The wordDict parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.

    解题思路:

    1. 此题在时间复杂度和空间复杂度上都很敏感,很容易出现TLE或者MLE,因此需要注意只存需要的内容,只做有用的运算。
    2. 首先对目标字符串的后半部分进行遍历,当后面的子字符串在字典中存在时,再讨论前面怎么分割。否则从前往后讨论,计算出到某些位置的前面字符串分割方法后,发现后面组成的词语在字典中不存在,就白白计算了。当求出所需子字符串的分割方法之后,将其存入map中,以便之后需要时直接访问。
    3. 在频繁需要在向量中查找某个元素是否存在时,可以考虑将向量的所有元素转存到set中,这样hash查找会很快。就是一种空间换时间的思路。

    刷题记录:

    1. 自己的算法一点也不优化,是从前往后递归的,浪费了很多空间和程序运行的时间。NO BUG FREE.

    141. Linked List Cycle

    Given a linked list, determine if it has a cycle in it.

    Follow up:
    Can you solve it without using extra space?

    解题思路:
    1. 定义一个快速指针fast(每次前进两个指针)和一个慢指针slow(每次前进一个指针)。如果没有cycle,fast会先到达链表的终点NULL,如果有NULL,在圆圈中循环,最后一定有一次,fast追上slow,两者相等,此时返回true。

    142. Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

    Note: Do not modify the linked list.

    Follow up:
    Can you solve it without using extra space?

    解题思路:
    1. 与上题一样,定义两个指针,一个一次前进两步,一个一次前进一步。如果循环存在,当它们第一次相遇(指向相同的结点时),假设走了num步,则slow指针前进了num步,fast指针前进了2*num步,多出来的num步应等于n*k(k为环的长度)。设链表的开头到cycle的开头距离为s,cycle的开头到相遇的地方距离为m,则num=s+m,s=num-m=n*k-m=(n-1)*k+k-m。相当于如果此时fast指针从相遇的地方以1个结点/步的速度前进s步,会走过n-1圈,然后k-m个结点,到达cycle的初始位置;因此,我们同时将slow重置为head,然后以一个结点/步的速度往后移,那么经过s步到达cycle的初始结点,此时会与fast相遇。将相遇作为循环终止条件,返回cycle的初始结点位置。

    刷题记录:

    1. 没能通过数学推导发现这层关系,需要深入掌握数学推导和观察的方法,NO BUG FREE

    143. Reorder List

    Given a singly linked list LL0→L1→…→Ln-1→Ln,
    reorder it to: L0→LnL1→Ln-1→L2→Ln-2→…

    You must do this in-place without altering the nodes' values.

    For example,
    Given {1,2,3,4}, reorder it to {1,4,2,3}.

     
    解题思路:
    1. 需要将链表的顺序重新排列,首先是要找到链表的尾结点位置,然后将中间到尾结点的所有结点链表顺序反转,便于在reorder过程中依次访问。下次在找中间结点和尾结点的过程中不要先计数结点的数量,然后再循环一半了,一定要定义两个指针,一个一次位移1个,一个一次位移2个,用这种方式来一次循环找到中间结点。无论算法多熟练的人,细节都是要一一推敲的,所以不用着急。

    144. Binary Tree Preorder Traversal

    Given a binary tree, return the preorder traversal of its nodes' values.

    For example:
    Given binary tree {1,#,2,3},

       1
        
         2
        /
       3
    

    return [1,2,3].

    Note: Recursive solution is trivial, could you do it iteratively?

    解题思路:

    1. 用迭代的方法进行二叉树的前序遍历,同样需要构造一个向量当作栈使用,如果当前指针指向不为空,则输出其结点值,并循环访问其左子结点。当左子结点为NULL时,栈顶元素出栈,并将工作指针指向其右子树结点,重复循环。

    145. Binary Tree Postorder Traversal

    Given a binary tree, return the postorder traversal of its nodes' values.

    For example:
    Given binary tree {1,#,2,3},

       1
        
         2
        /
       3
    

    return [3,2,1].

    Note: Recursive solution is trivial, could you do it iteratively?

    解题思路:

    1. 两种方式:1 直接按照顺序将根结点入栈,然后循环将其左子结点入栈直到为空。需要定义一个和栈同顺序的bool向量用来表明栈顶元素的右子树是否已经访问过,如果没有访问过,则工作指针指向其右子树,继续循环;如果访问过,则把当前结点出栈,并将val值加入结果向量中。2 与前序遍历相同的思路,先访问根结点,再访问右子树,再访问左子树。最后将结果向量反转输出即可。

    146. LRU Cache

    Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.

    get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
    put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

    Follow up:
    Could you do both operations in O(1) time complexity?

    Example:

    LRUCache cache = new LRUCache( 2 /* capacity */ );
    
    cache.put(1, 1);
    cache.put(2, 2);
    cache.get(1);       // returns 1
    cache.put(3, 3);    // evicts key 2
    cache.get(2);       // returns -1 (not found)
    cache.put(4, 4);    // evicts key 1
    cache.get(1);       // returns -1 (not found)
    cache.get(3);       // returns 3
    cache.get(4);       // returns 4
    

    解题思路:

    1. 要求根据key值读取对应value值,时间复杂度为O(1)时,一定是选择map结构进行存储。问题的关键在于构造一个合适的结构来存储所有key的活跃度排名情况,由于向量删除某个元素的时间复杂度为O(n),因此不合适,由此想到链表,因为如果对某个key-value进行访问过后,需要将其原活跃度删除,放置在最新活跃度的位置上,删除元素时间复杂度为O(1)的结构为list,除此之外,map结构还需要存储对应key在活跃度链表中的位置(list<int>::iterator),以便于以时间复杂度为O(1)访问到。
    2. 需要掌握更多容器的成员函数,包括list.erase(iterator),list.insert(iterator,int),map.erase(key),map也有size()函数。

    147. Insertion Sort List

    Sort a linked list using insertion sort.

    解题思路:

    1. 直接插入排序是从前往后遍历链表的元素,每访问一个,就将其插入到之间已经排好序的链表中,因此每次内部循环都需要从前往后找出结点应该插入的位置。注意循环条件,链表问题经常会定义一个空结点作为辅助helper来帮助更好的完成代码的统一性。

    148. Sort List

    Sort a linked list in O(n log n) time using constant space complexity.

    解题思路:

    1. 由于链表结构进行增删,插入时时间复杂度为O(1),所以很适合用归并排序的方法。归并排序用递归算法时间,递归过程占用的是栈空间,不算做空间复杂度,只有堆内存的使用才算作空间复杂度。
    2. 归并排序的思路是,对一条完整的链表进行排序,等于讲它的前一半和后一半链表分别进行排序后,再将两条链表合并在一起。当链表为NULL或者只有一个结点时,直接返回头指针,否则继续用归并排序进行迭代。
    3. 合并函数需要定义一个辅助结点,注意循环的终止条件。

    149. Max Points on a Line

    Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

    解题思路:

    1. 判断在一条直线上的最大点数,需要计算每两个点之间的斜率,来判断是否后者是否在前者的直线上,因此时间复杂度为O(n^2)。采用循环的方式,找寻包含第一点的所有直线的最大点数,用map<long double,int>来进行存储,key是斜率值,value为最大点数,斜率相同则在同一条直线上。注意要单独统计与目标点完全相同的点数,因为这部分点数可以算在任何一条直线中。当斜率不存在,即与横坐标垂直时,斜率赋值为INT_MAX。找寻完之后,在循环第二个点,忽略第一个点,依此类推。
    2. 用for(map<long double, int>::iterator it = amount.begin();it != amount.end();it++)迭代器可以实现对字典的遍历。要注意long double 和 double的不同,double是8字节,而long double根据编译器的不同而不一样,精度不够大时差别极小的斜率识别不出来。

    150. Evaluate Reverse Polish Notation

    Evaluate the value of an arithmetic expression in Reverse Polish Notation.

    Valid operators are +-*/. Each operand may be an integer or another expression.

    Some examples:

      ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
      ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6
    

    解题思路:

    1. Reverse Polish Notation是字符串向量,操作数在前,操作符在后(存储的时候先存储两个操作数,然后存储一个操作符)。先读取的操作数可能后用到,后读取的操作数可能马上就用到,根据这个特性选择栈空间作为数据结构,遍历字符串向量,当遇到数时加入栈中,遇到操作数时将前面存放的两个操作数出栈,进行对应的运算,再将运算结果存入栈中。
    2. 需要考虑特殊情况,当向量中只有一个数时,直接返回这个数即可。

    151. Reverse Words in a String

    Given an input string, reverse the string word by word.

    For example,
    Given s = "the sky is blue",
    return "blue is sky the".

    Update (2015-02-12):
    For C programmers: Try to solve it in-place in O(1) space.

     

     
    解题思路:
    1. 需要理清题目表达的意思,将给定的字符串非空格连续字符的顺序反转输出,且不要保留字符串前后的空格,中间的连续空格也只保留一个即可。

    152. Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest product.

    For example, given the array [2,3,-2,4],
    the contiguous subarray [2,3] has the largest product = 6.

    解题思路:

    1. 由于不确定当前值的符号,因此笼统的来看,包含当前位置在乘积中的最大值来自于前一位置的最小值和最大值分别与当前位置的值相乘,和当前位置本身其中的最大值;最小值同理。如果最大值和最小值符号不同,其实根据当前位置的符号很容易判断最大最小值,但是存在刚开始的情况,最大最小值符号不同,因此从不同位置开始乘可能值更小。

    刷题记录:

    1. 思路有点混乱,需重写一遍,NO BUG FREE。

    153. Find Minimum in Rotated Sorted Array

    Suppose an array sorted in ascending order 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).

    Find the minimum element.

    You may assume no duplicate exists in the array.

    解题思路:
    1. 使用二分法查找经过旋转后的排序向量,当头元素的值小于尾元素时,说明未经旋转,头元素为最小值。否则根据mid=(low+high)/2的元素值与头元素比较得出mid在哪边队列中,分别对low和high做不同的更改。

    154. Find Minimum in Rotated Sorted Array II

    Follow up for "Find Minimum in Rotated Sorted Array":
    What if duplicates are allowed?

    Would this affect the run-time complexity? How and why?

    Suppose an array sorted in ascending order 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).

    Find the minimum element.

    The array may contain duplicates.

    解题思路:
    1. 在存在重复元素时,可能出现nums[mid]和nums[low]相等的情况,此时并不知道应该如何变换low和high,不知mid是在向量的头部重复,还是在向量的尾部。所以需要做一个小操作,将low++,然后进行下一次循环。
    2. 如果使用的是low++的话,循环结束后应该返回的元素就是nums[high]。

    155. Min Stack

    Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

    • push(x) -- Push element x onto stack.
    • pop() -- Removes the element on top of the stack.
    • top() -- Get the top element.
    • getMin() -- Retrieve the minimum element in the stack.

    Example:

    MinStack minStack = new MinStack();
    minStack.push(-2);
    minStack.push(0);
    minStack.push(-3);
    minStack.getMin();   --> Returns -3.
    minStack.pop();
    minStack.top();      --> Returns 0.
    minStack.getMin();   --> Returns -2.
    

    解题思路:

    1. 只用一个向量来构建栈,需要将存储的数和当前的最小值都存入到同一个栈里面去。

    160. Intersection of Two Linked Lists

    Write a program to find the node at which the intersection of two singly linked lists begins.

     

    For example, the following two linked lists:

    A:          a1 → a2
                       ↘
                         c1 → c2 → c3
                       ↗            
    B:     b1 → b2 → b3
    

    begin to intersect at node c1.

     

    Notes:

    • If the two linked lists have no intersection at all, return null.
    • The linked lists must retain their original structure after the function returns.
    • You may assume there are no cycles anywhere in the entire linked structure.
    • Your code should preferably run in O(n) time and use only O(1) memory.
     
    解题思路:
    1. 使用数学推理的过程,将第一个链表顺序反转,然后从第二个链表的头部循环往下遍历,如果两条链表的结点存在交叉,那么从B链表头部循环能访问到A链表的头部。记录A链表的结点长度num1和B链表的结点长度num2,和B链表头部到A链表的头部的长度num3可以计算出从B链表头部到交叉结点的长度step=(num3+num2-num1-1)/2。
    2. 更简单的方式是定义A,B链表的头结点,同时向后访问,如果地址相同则返回,否则继续往下,当A链表指针访问到尾部时,指向B链表头部,当B链表指针访问到尾部时,指向A链表头部。如果存在交叉,那么它们一定会在第二次重新出发后相遇,否则会经过相同的长度同时变成NULL。

    162. Find Peak Element

    A peak element is an element that is greater than its neighbors.

    Given an input array where num[i] ≠ num[i+1], find a peak element and return its index.

    The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.

    You may imagine that num[-1] = num[n] = -∞.

    For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2.

    解题思路:
    1. 将nums[-1]看作无穷小,因此除非序列是一个一直递增的序列,那么顶峰值出现在最后一个元素(nums[n]也是无穷小);否则只要序列出现当前元素比前一个元素小,那么前一个元素就一定是一个顶峰值,返回其index即可。
    2. 使用二分法进行查找,mid=(low+high)/2,将mid位置上的值与mid+1的值进行比较,如果nums[mid]<nums[mid+1],那么序列右半部分一定存在顶峰值,low=mid+1;如果nums[mid]>nums[mid+1],那么序列左边一定存在顶峰值,high=mid。直到low=high,为所求index。

    164. Maximum Gap

    Given an unsorted array, find the maximum difference between the successive elements in its sorted form.

    Try to solve it in linear time/space.

    Return 0 if the array contains less than 2 elements.

    You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.

    解题思路:
    1. 在时间复杂度为O(n)的限制条件下,对非排序数组求在排序情况下连续元素的最大差距。尝试使用的是用set结构存储下所有的int元素,由于hash存储,会自动按照元素的大小排序存储。再用set<int>::iterator即可完成遍历并求最大差距。
    2. 既然对空间复杂度没有要求,可以使用桶排序的方式,将min~max的连续范围平均划分为n-1个区间(n为元素的个数),那么连续数之间的最大间隔一定是大于(max-min)/(n-1)的,因此遍历数组,来确定每个元素在哪个桶中,以此来计算和存储每个桶的最大值和最小值,用后一个桶的最小值减前一个桶的最大值即为可能出现的最大间隔。
    3. 尤其注意float和double的区别,范围和精度是不一样的。它们由符号位,指数位和尾数位组成,由于float与int一样都为4字节,但是float的尾数位只有23bits,因此float的精度只有6~7位有效数字,但是范围可能很大。

    165. Compare Version Numbers

    Compare two version numbers version1 and version2.
    If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.

    You may assume that the version strings are non-empty and contain only digits and the . character.
    The . character does not represent a decimal point and is used to separate number sequences.
    For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision.

    Here is an example of version numbers ordering:

    0.1 < 1.1 < 1.2 < 13.37
     
    解题思路:
    1. 版本号的比较,依次读取一级、二级、三级版本号,如果高级别的版本号之间存在大小关系,可以直接返回;相同则继续比较下一级版本号。当某个版本号结束后,应当默认之后的级别版本为0,继续比较,比如1.0 = 1,直到出现大小关系或者两者都比较完(返回0,表示版本相同)。

    166. Fraction to Recurring Decimal

    Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.

    If the fractional part is repeating, enclose the repeating part in parentheses.

    For example,

    • Given numerator = 1, denominator = 2, return "0.5".
    • Given numerator = 2, denominator = 1, return "2".
    • Given numerator = 2, denominator = 3, return "0.(6)".
     
    解题思路:
    1. 该问题的难点有几个:1、首先要根据参数的正负,判断结果的正负符号。再将参数取绝对值,直接将INT_MIN取绝对值会出现out_of_range,因此要先将int转化为long long类型(8字节),注意看自己机器的long int类型是否与int类型的字节数一样。2、在存储字符串的迭代器作为位置的时候,随着更多的字符push_back到字符串的尾部,前面存储的迭代器可能会失效,超出范围,具体的什么原因我也不清楚,最后是存储字符的index比较安全和稳定。
    2. 思路是在求小数部分时,分数相除为有限小数或者无限循环小数,因此要存储下小数开始循环的位置,用map进行存储,key为余数值,value为结果的位置。当两次计算得到的余数相同时,计算结果一定会开始重复循环。在之前存储的位置和结尾分别加上'('和')'即可。

    167. Two Sum II - Input array is sorted

    Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.

    The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

    You may assume that each input would have exactly one solution and you may not use the same element twice.

    Input: numbers={2, 7, 11, 15}, target=9
    Output: index1=1, index2=2

    解题思路:
    1. 由于数组是一个已经经过排序后的,因此可以定义两个index变量分别从前和从后遍历。如果nums[i]+nums[j]==target,则返回标签;如果比target大,则j--;比target小,则i++。直至相等。

    168. Excel Sheet Column Title

    Given a positive integer, return its corresponding column title as appear in an Excel sheet.

    For example:

        1 -> A
        2 -> B
        3 -> C
        ...
        26 -> Z
        27 -> AA
        28 -> AB 
     
    解题思路:
    1. 由于字母代表的数字是不包含0的,所以不可能让余数为0。十位上的数字表示的底数为26,百位上的底数为26^2,应该用目标数除以26取余。如果余数为0,说明刚好满26,当前位用'Z'表示即可,并不需要高位进位,所以将商的结果减一,继续循环,直到商为0。

    169. Majority Element

    Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

    You may assume that the array is non-empty and the majority element always exist in the array.

    解题思路:
    1. 第一种思路是采用hash map<int,int>存储每个元素,及其出现的次数,当次数大于n/2时返回。要注意如果key值在map中不存在时,直接执行map[key]++语句,会将其初始值作为0处理。
    2. 第二种思路更巧妙,遍历数组,存储当前出现超过当前一半的数记作majority以及它出现的次数,当访问的数与majority相等时,count++;当不等时,count--;如果count减到0之后,就将majority改变成当前元素nums[i]。如果有一个元素出现次数超过整个向量的一半的话,最后majority一定是等于它的。因为如果majority在前半部分出现的次数多,那么后面不会减到0;如果majority在前面出现的不多,那么前面的majority一定不是真的majoriry,也说明了后半部分的真正majority是超过一半的,所以其他所有元素都保留不下来。

    171. Excel Sheet Column Number

    Related to question Excel Sheet Column Title

    Given a column title as appear in an Excel sheet, return its corresponding column number.

    For example:

        A -> 1
        B -> 2
        C -> 3
        ...
        Z -> 26
        AA -> 27
        AB -> 28 

     
    解题思路:
    1. 相比于数值转换excel title的镜像问题,这个就简单很多了,每个位置上的权值是26^n,n为右边剩下字符的位数。用26乘之前的结果加上当前位置上的字符表示的的数就可以了。

    172. Factorial Trailing Zeroes

    Given an integer n, return the number of trailing zeroes in n!.

    Note: Your solution should be in logarithmic time complexity.

    解题思路:

    1. 一个数的末尾有多少个尾随零,说明能被多少个10整除,而且剩余部分不再能被10整除。由于10可以写成2×5的因子组合,说明阶乘中每出现一个5,结果就能多整除一个10(因为因子2肯定是多于5的),而且余数部分肯定无法被5整除。因此问题转换成了阶乘序列能分解出多少个因子5。
    2. 由于每5个数,就会出现一个因子5;每25个数,就会有一个5^2;每125个数就会出现一个5^3...因此因子5的总数量为n/5+n/5^2+n/5^3+...直到商为0。

    173. Binary Search Tree Iterator

    Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.

    Calling next() will return the next smallest number in the BST.

    Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.

     
    解题思路:
    1. 由于本题对内存有限制为O(h),h为二叉树的高度,所以不能用前序遍历的方法直接将结点val值的大小顺序排出来(后者的时间复杂度为O(n),n为结点数量)。还是使用向量模拟栈的存储结构,但是在入栈时分步骤完成,在构造函数中完成一部分,在每次查找最小值的过程中完成一部分。
    2. 首先将根节点的所有左子树结点入栈,栈顶结点即为树的最小值,每当访问一次树的最小值结点时,就将其出栈,然后将其所指向的右子树的结点和其左子树入栈,这样来保持栈顶元素是剩下的结点中最小的。

    174. Dungeon Game

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess.

    The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately.

    Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).

    In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.

     

    Write a function to determine the knight's minimum initial health so that he is able to rescue the princess.

    For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.

    Notes:

    • The knight's health has no upper bound.
    • Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.

    解题思路:

    1. 此题的关键点在于骑士到达地牢的每个位置时的血量至少为1。如果使用从前往后的动态规划,只知道前面走过地牢的情况,并不知道后面的情况,所以并不好判断究竟那条路需要的初始血量最少,因为存在大量的补血地牢,加上不知道后面需要多少血量支撑。但是使用从后往前的动态规划就很清楚了,我们知道到达最后一个地牢时所需要的最少血量,就可以求解到达它上面一格和左边一格所需要的最少血量,因为已经得出了下面和右边部分的地牢的最少血量,所以只要当前结点能存活下来(血量>=1)就一定能顺利走到终点。注意:当最少血量为0或负时,重置为1。
    2. 使用递归的方法也可以求所有路径下到达右下角所需的最少血量,但是当地牢结构较大时会出现TLE的问题。

    刷提记录:

    1. 是一个很好的DP问题,锻炼变通的思维,从前往后不行时,就要尝试从后往前。

    179. Largest Number

    Given a list of non negative integers, arrange them such that they form the largest number.

    For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.

    Note: The result may be very large, so you need to return a string instead of an integer.

    解题思路:
    1. 本题的难点是以合适的方式对整型数组进行排序,我的思路是将数组所转换得到的字符串一个字符一个字符的比较,思路比较复杂,在细节处理上要费很多工夫。
    2. 比较两个整型字符串谁放在前比较大最直接和简单的思路就是,分别将num1+num2与num2+num1(颠倒顺序)得到的字符串直接进行比较,如果前者大于后者,那么将num1放置在前面;反之将num2放置在前面。

    187. Repeated DNA Sequences

    All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

    Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.

    For example,

    Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT",
    
    Return:
    ["AAAAACCCCC", "CCCCCAAAAA"].
    

    解题思路:

    1. 这个问题的整体思路就是通过一次遍历,将出现过的DNA序列通过hash存储下来,然后判断是否有重复。但是由于hash存储的结构为string类型,消耗的空间较大,会导致memory limit excess的问题,为了解决这个问题,我们将每个string转换为代表它的整型数来存储。避免整型数过大,我们就采用二进制的方式,一共只有四个字符,用00,01,10,11表示,各自占用两个bit空间,10个字符一共占用20个bit空间,在int所能表示的范围内。循环遍历10个字符时,将已经得到的数字左移两个bit,然后将新加入的字符代表的bit用|符号加入到末尾。
    2. 一定要注意for循环的条件,如果s.size()-10出现了负数的情况是一定会从问题的,因为string.size()的返回值是unsigned int类型,而且unsigned int是比int更高级的类型,运算的结果会隐式转换为unsigned int类型,是一个正数。

    188. Best Time to Buy and Sell Stock IV

    Say you have an array for which the ith element is the price of a given stock on day i.

    Design an algorithm to find the maximum profit. You may complete at most k transactions.

    Note:
    You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

     
    解题思路:
    1. 用一个二维数组或行向量作为存储结构都是可行的,profit[k][j]表示最多经过k次交易时,到第j个商品(包括是否售卖它)的最大收益。那么profit[k][j] = max(profit[k][j-1] , prices[j] + profit[k-1][jj-1] - prices[jj]) = max(profit[k][j-1] , prices[j] + max (profit[k-1][jj-1]-prices[jj])),其中0 <= jj < j。因此在进行多一次转换交易,遍历的过程中就用一个变量将profit[k-1][jj-1]-prices[jj]的最大值存储下来,减少了重复的循环操作。
    2. 为什么不用跟少一次交易的最大收益进行比较就能得到最多k次交易的最大收益?这是由动态规划的过程决定的,因此无论k为多少时,profit[k][0]、profit[k][1]和profit[k][2]都是相同的,也就是说它们可以表示最多k次交易的最大值,所以在动态规划时得到后面的值也是包含了不到k次的交易的情况。max操作是将最多k次操作时,是否包含第j个商品的售卖作为分类的。可以用数学归纳法证明这一点。
    3. 当k特别大时,会出现TLE的情况,实际上只要k>=n/2时,就能够售卖所有的股票,所以只要有后面的价格大于前面的价格的情况,都可以作为利润加入到总利润中。
    4. terminate called after throwing an instance of 'std::bad_alloc' 这种报错提示指的是内存分配不足了。

    刷题记录:

    1. 第一次,NO BUG FREE.

    189. Rotate Array

    Rotate an array of n elements to the right by k steps.

    For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].

    Note:
    Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.

     

    解题思路:

    1. 在使用迭代器的时候,如果向量发生了增、删、插入等长度的变化,原来使用和定义的迭代器一定会失效,一定要重新定义!所以在查看和更改数值时可以使用迭代器,但是如果需要多次在向量发生变化时使用迭代器就不是很安全了,使用下标比较好。
    2. 此题如果不允许申请额外的内存空间,可以采用反转的方法,先将整个向量反转,即前后元素交换,然后再将前k部分反转和后n-k部分反转就可以了。

    190. Reverse Bits

    Reverse bits of a given 32 bits unsigned integer.

    For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).

    Follow up:
    If this function is called many times, how would you optimize it?

     
    刷题记录:
    1. 此题需要将表示无符号整型数的二进制表示反转,使用bit操作运算符来完成,首先通过n & 1取n的最低位,加入到res中,具体操作是res = (res << 1) + (n & 1);然后再将n >>= 1,将最低位移出去,次低位移至最低位。循环32次就可以完成所有二进制bit位的反转。

    191. Number of 1 Bits

    Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight).

    For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3.

     
    解题思路:
    1. 要计算出一个无符号整型数的二进制表示中'1'的个数,需要计算遍历其所有bit上的值,用n&1来取最低位的值,如果为'1',则num++;然后n>>=1将其移出。循环32次,就可以对所有bit位做出判断。

    198. House Robber

    You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

    Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

     
    刷题记录:
    1. 使用动态规划的方法,当前位置的房子分为rob与notrob两种情况,rob后的最大收益等于前一个位置notrob的最大收益加上该房子的价值;notrob后的最大收益为前一个位置rob与notrob中的较大值。

    199. Binary Tree Right Side View

    Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

    For example:
    Given the following binary tree,

       1            <---
     /   
    2     3         <---
          
      5     4       <---
    

    You should return [1, 3, 4].

     
    解题思路:
    1. 第一种方式,选择层序遍历,我们可以发现实际上从右侧可以看到的树的结点就是每层层序遍历最末尾的结点。在每层循环时,首先将其末尾结点的val加入到res向量中,然后再顺序访问指针得到其下一层的指针加入链表中,层序遍历使用链表的存储结构是最好的。
    2. 第二种思路,使用递归的方式,传递当前结点所处的树的位置深度,与res向量的大小进行比较,如果和res向量相同,说明当前层还没有存入结点,因此把该结点值存入。对当前结点执行函数,先递归其右子树,再递归其左子树,保证每层优先递归到的结点是当前层最右侧的。

    200. Number of Islands

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

    Example 1:

    11110
    11010
    11000
    00000

    Answer: 1

    Example 2:

    11000
    11000
    00100
    00011

    Answer: 3

     
    解题思路:
    1. 定义一个递归函数,如果某个点的位置是'1'(即为一个island),能够找出并标识所有和它相连的岛屿,标记为'2',一方面防止之后的遍历过程再次访问到,一方面与表示water的'0'区分开,以便于求解完成后恢复参数。
    2. 循环遍历整个数组,如果某一个位置为island,那么岛屿数加1,并调用递归函数,找到和标记所有与其相连的岛屿。一直执行到遍历完整个数组,然后再根据'2'的标记进行恢复。

    201. Bitwise AND of Numbers Range

    Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.

    For example, given the range [5, 7], you should return 4.

     
    解题思路:
    1. 此题需要把范围内的所有数按位与,因此只要在从m到n的范围内出现过进位的bit位在结果中一定为0,我们只需要找m→n的最高进位即可,最高位有进位,那么低位一定也有进位,地位经过bit &运算后在结果中一定为0。
    2. 依次取高位,我们需要对m和n做与INT_MIN的&运算,因为INT_MIN在内存中是用1000000000000表示的。如果结果为INT_MIN,说明最高位为'1';结果为0,说明最高位为'0'。结果相同,就在末位加上对应的bit,结果不同直接在末尾全部补0。

    202. Happy Number

    Write an algorithm to determine if a number is "happy".

    A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

    Example: 19 is a happy number

    • 12 + 92 = 82
    • 82 + 22 = 68
    • 62 + 82 = 100
    • 12 + 02 + 02 = 1
     
    解题思路:
    1. 定义一个私有变量,数据集合用来存储在计算数字平方和的过程中出现过的数,如果出现重复的数,那么一定会进入循环内返回false。如果当前数为1,则返回true。如果既不等于1,也未重复出现过,那么将该数加入集合中,并计算其数字平方和,递归调用计算该数字是否为happy number。

    203. Remove Linked List Elements

    Remove all elements from a linked list of integers that have value val.

    Example
    Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
    Return: 1 --> 2 --> 3 --> 4 --> 5

     
    解题思路:
    1. 在链表中移除val值指定的元素,直接遍历链表即可,当前指针的元素val值为目标值,就将前一指针指向当前指针的next即可,时间复杂度为O(n),空间复杂度为O(1)。因为要完成该过程,至少对链表中的每个元素都访问一遍,所以时间复杂度至少为O(n),以此确定我的方法就是最优解。

    204. Count Primes

    Description:

    Count the number of prime numbers less than a non-negative number, n.

     
    解题思路:
    1. 定义一个长度为n的bool类型向量,用来存储对应元素是否为质数,由于一个元素为非质数,一定是等于比它小的两个元素的乘积,所以只要我们考虑了所有比它小的元素的乘积,但是它对应的位置bool仍然没有被改为true。说明任何比它小的两个元素乘积都不等于它,说明它是个质数。
    2. 注意两个整型数相乘的结果默认还是一个int类型,如果乘积结果超出int所能的表示范围会报错,runtime error。此时需要强制类型转换为static_cast<long long>。

    205. Isomorphic Strings

    Given two strings s and t, determine if they are isomorphic.

    Two strings are isomorphic if the characters in s can be replaced to get t.

    All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.

    For example,
    Given "egg""add", return true.

    Given "foo""bar", return false.

    Given "paper""title", return true.

    Note:
    You may assume both s and t have the same length.

    解题思路:
    1. 跟字符有关的问题,往往并不需要用到map结构,由于表示字符的ASCII码与字符是一一对应的关系,所以用一个256维的一维数组存储就可以了。定义两个数组分别存储两个字符串中字符的出现情况,初始化为0,如果遍历的对应字符的位置数字都为0,那么为他们存储一个独一无二的数字作为他们的对应关系标识,用count表示,每次存储完后count++。在之后的遍历中,如果数值不相等,说明不是对应的,返回false。
    2. 跟字符有关的问题定义的数组都需要是256的大小,因为ASCII码是用一个字节表示,所以最多能表示256个字符,其中前128个为常用字符,后128个为扩展字符。

    206. Reverse Linked List

    Reverse a singly linked list.

    click to show more hints.

    Hint:

    A linked list can be reversed either iteratively or recursively. Could you implement both?

    解题思路:

    1. 返回头指针的函数也可以进行迭代完成链表的反转,如果要正向的完成一些操作,就写在调用迭代函数之前,但是如果想要反向的完成一些操作,就写在迭代函数之后。本题就是这样,迭代函数其实返回的东西并没有什么意义,只是找到末尾结点后一层层返回而已。但是在返回的过程中,执行语句使后面的结点的next指针指向前一个结点,完成链表的反转。

    刷题记录:

    1. NO BUG FREE.

    207. Course Schedule

    There are a total of n courses you have to take, labeled from 0 to n - 1.

    Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

    Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

    For example:

    2, [[1,0]]

    There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

    2, [[1,0],[0,1]]

    There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

    Note:

    1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
    2. You may assume that there are no duplicate edges in the input prerequisites.

    解题思路:

    1. 拓扑排序是对有向无圈图的顶点的一种排序,这个排序的结果是如果存在一条vi到vj的路径,那么排序中vi在vj的前面。每个顶点的入度是指向它的单向边的条数。在题目中,我们将课程与先修课程的关系转换为顶点之间单向边的关系,我们一开始只能学习没有任何先修课程的课程,也就是入度为0的顶点,然后根据入度为0的顶点与其他顶点之间的单向边关系,修改与其相连的其他顶点的入度,将其减1,如果为0则加入队列中。按照这样的顺序来访问所有的结点就是拓扑排序,如果图中存在单向边构成的环,那么其所有顶点的入度都不为0,因此无法访问(无法进修该课程),此时队列为空,跳出循环,比较已经访问过的入度为0的结点数与总结点数,如果相等,则可以学习完;否则不能学习完。
    2. 邻接矩阵是图比较理想的存储结构,所以首先应该把题中定义的参数的结构转换为邻接矩阵来存储。用DFS或者BFS的方法来遍历图。

    208. Implement Trie (Prefix Tree)

    Implement a trie with insertsearch, and startsWith methods.

    Note:
    You may assume that all inputs are consist of lowercase letters a-z.

    解题思路:
    1. 字典树或者前缀树是一棵多分支树,每个树结点或者分叉代表着一个字母,每个结点中包含一个数量大小为26的node*的指针数组,分别指向下一分支的26个字符。(注意在定义指针数组时,一定要将指针初始化为NULL,如果不经初始化直接访问会报错)。
    2. 结点中还需定义一个bool类型的变量,表示该结点到根结点的分支所表示的字符串是否为我们插入的一个word,如果是,bool型为true;反之为false,表示当前结点到根结点只是word的一部分而已。

    209. Minimum Size Subarray Sum

    Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.

    For example, given the array [2,3,1,2,4,3] and s = 7,
    the subarray [4,3] has the minimal length under the problem constraint.

     

     
    解题思路:
    1. 定义两个index分别用来标识子数组的起始位置和终止位置,当子数组的和sum<目标数时,终止位置后移,直到子数组和大于或等于目标数;此时将起始位置后移,并从sum中减去对应的值,直到sum由>=s变化到<s,此时的起始位置和终止位置为临界状态,当前的最短长度为j-i+2,从i-1~j的子数组长度大于目标数。循环直到j=nums.size()-1时结束。

    210. Course Schedule II

    There are a total of n courses you have to take, labeled from 0 to n - 1.

    Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

    Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.

    There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

    For example:

    2, [[1,0]]

    There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1]

    4, [[1,0],[2,0],[3,1],[3,2]]

    There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. Another correct ordering is[0,2,1,3].

    Note:

    1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
    2. You may assume that there are no duplicate edges in the input prerequisites.

    解题思路:

    1. 与207题的思路类似,但是采用深度优先遍历的方式(DFS),对入度为0的结点访问并加入课程顺序向量中后,优先对与其相连的结点进行讨论,对与其相连的结点的入度减1,如果此时结点的入度等于0之后,对该结点递归调用。一直到把最初所有入度为0的结点循环结束。要注意定义一个数组暂存原来的入度,因为在递归调用的过程中,会修改入度向量,使用同一个会导致对某些课程的重复访问。

    211. Add and Search Word - Data structure design

    Design a data structure that supports the following two operations:

    void addWord(word)
    bool search(word)
    

    search(word) can search a literal word or a regular expression string containing only letters a-zor .. A . means it can represent any one letter.

    For example:

    addWord("bad")
    addWord("dad")
    addWord("mad")
    search("pad") -> false
    search("bad") -> true
    search(".ad") -> true
    search("b..") -> true
    
     
    解题思路:
    1. 添加或查找单词问题都用字典树的存储结构来解决。当查找的单词中存在可以代表任何字符的'.'时,需要对所有的可能进行循环,递归调用完成。

    212. Word Search II

    Given a 2D board and a list of words from the dictionary, find all words in the board.

    Each word must 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 in a word.

    For example,
    Given words = ["oath","pea","eat","rain"] and board =

    [
      ['o','a','a','n'],
      ['e','t','a','e'],
      ['i','h','k','r'],
      ['i','f','l','v']
    ]
    

    Return ["eat","oath"].

    Note:
    You may assume that all inputs are consist of lowercase letters a-z.

    click to show hint.

    You would need to optimize your backtracking to pass the larger test. Could you stop backtracking earlier?

    If the current candidate does not exist in all words' prefix, you could stop backtracking immediately. What kind of data structure could answer such query efficiently? Does a hash table work? Why or why not? How about a Trie? If you would like to learn how to implement a basic trie, please work on this problem: Implement Trie (Prefix Tree) first.

     
    解题思路:
    1. 与在一个board中搜索一个单词的情形不同,此题需要在board中搜索一系列单词,找出它们中出现的单词。如果一个个单词去搜索,会导致时间复杂度过大,同一个board进行重复的递归。因此我们要建立良好的数据结构,使得通过一遍board的遍历和迭代,找到所有在向量中出现的单词。这个良好的数据结构就是字典树(由一系列单词组成的多分支树)。
    2. 建立了字典树后,我们通过对board的循环,就可以从树的根结点对board对应位置的字符进行比较。如果board递归当前组成的字符串序列为一个单词,就添加到结果向量中;如果不是,就继续对其邻接的四个字符进行递归,如果代表当前字符的指针为空或者board[i][j]='#'(表示当前序列中该字符已经使用过)就可以返回。对周围的所有位置进行递归以后,记得将转换成'#'字符的位置恢复之前的字母。
    3. void * memset ( void * ptr, int value, size_t num );可以迅速完成对大量内存空间的初始化,将指针ptr所指向的开始位置的连续num bytes的内存空间初始化为val。例如:node* letter[26];memset(letter, NULL, sizeof(node*)*26);

    213. House Robber II

    Note: This is an extension of House Robber.

    After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

    Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

    解题思路:

    1. 可以利用前一个版本问题的思路,构建两个变量分别存储rob当前位置和notrob当前位置的最大收获(这是在头部可以任意选择rob和notrob,尾部也可以选择rob和notrob的情况)。但是由于环的存在,本题中的首尾是相互约束的,所以需要分类将本体转化为前面的情况,第一张情况,假设第一个结点notrob,那么从第二个结点到最后一个结点的序列是满足的(第二个结点和最后一个结点都不受限制);第二张情况假设最后一个结点notrob,那么从第一个结点到最后一个结点的序列是满足情况的。最优结果一定是上述两种情况的最优解,因为头尾至少有一个notrob。

    214. Shortest Palindrome

    Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.

    For example:

    Given "aacecaaa", return "aaacecaaa".

    Given "abcd", return "dcbabcd".

     
    解题思路:
    1. 此题围绕的核心是求从字符串开头往后的最长的回文字符串。求一个字符串是否为回文字符串,很好的方式是将字符串反转,比较和原字符串是否相同。因此我们将原字符串反转之后加到原字符串之后,然后使用KMP的方法求整个字符串的与后缀相同的最长前缀,就是最长的回文字符串。然后将非回文的部分反转后插入到原字符串的前面就得到结果了。
    2. KMP方法是使用合适的存储结构记录下目标字符串的内部结构,来减少比较的过程中无畏的遍历。定义一个与目标字符串同等长度的next向量,用来存储到字符串的对应位置,最长的相同的前缀和后缀长度。在比较时,如果不相等,则跳至最长相等的前缀位置继续比较,直至为恢复到0。

    刷题记录:

    1. NO BUG FREE.

    215. Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

    For example,
    Given [3,2,1,5,6,4] and k = 2, return 5.

    Note: 
    You may assume k is always valid, 1 ≤ k ≤ array's length.

     
    解题思路:
    1. 此题使用快速排序的方法是最合适的,因为快速排序是找当前数组第一个元素在整个数组当中的准确位置,而题目的要求就是要找在排序数组(从大到小)中处于k-1位置的数。
    2. 可以定义快速排序的递归函数,返回最后确定的第一个元素的位置,如果这个位置=k-1,就直接返回当前值即可;如果位置pivot>k-1,把right=pivot-1,即对左边的数组继续进行排序,因为第k个最大的数一定在左边;如果pivot<k-1,那么将left=pivot+1,继续对数组的右边进行排序,第k个最大的数一定在右边。当left=right时,跳出循环,nums[left]就是我们需要找的数。

    216. Combination Sum III

    Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.


    Example 1:

    Input: k = 3, n = 7

    Output:

    [[1,2,4]]
    

    Example 2:

    Input: k = 3, n = 9

    Output:

    [[1,2,6], [1,3,5], [2,3,4]]
    
     
    解题思路:
    1. 确定数量确定范围的数叠加等于某一目标值的问题。使用循环加迭代就好了,对加入的新元素在给定范围内循环,如果允许重复数,那就从前一个数开始;如果不允许重复数,就从前一个数+1的结果开始循环。如果加入数的数量等于要求的数量,而且目标值等于0,就找到了一个合适的组合,加入到最终的结果中即可。

    217. Contains Duplicate

    Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.

    解题思路:
    1. 用集合来存储数组中的元素,如果存在相同的数,就返回true;如果集合中不存在,则把当前数加入到集合中。直到遍历结束也没有返回true的话,就返回false表示向量中不存在相同的数

    218. The Skyline Problem

    A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings collectively (Figure B).

    BuildingsSkyline Contour

    The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.

    For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .

    The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour.

    For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].

    Notes:

    • The number of buildings in any input list is guaranteed to be in the range [0, 10000].
    • The input list is already sorted in ascending order by the left x position Li.
    • The output list must be sorted by the x position.
    • There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...]
     
    解题思路:
    1. 自己的思路是每次对当前矩形和下一个与其相邻最近的矩形进行讨论,分为高度相同,高度小于,高度大于三种情况。将多出来的部分划分为小矩形存入专门的优先级队列中,注意队列中也要根据起始位置进行排序,所以选择优先级队列。注意优先级队列的写法,比较函数cmp返回true,说明后者的优先级较高,排在队列的前面。
    2. 答案提供的思路比较复杂,但是写法比较简单,不用对矩形进行分割,定义了一个pair<int,int>的优先级队列,first参数为矩形的高度,second参数为矩形的结束位置。根据优先级队列是否为空,来给curX初始化:如果队列为空,初始化为当前矩形的左边界,并将以curX为左边界的所有矩形加入到队列中,如果高度发生变化,将现在的高度和curX加入返回值变量中;如果队列不为空,将队列最前(最高的矩形)的右边界赋给curX,如果当前矩形的左边界buildings[i][0]是小于等于curX的,就模仿上边操作加入队列中,如果是大于curX的,就清理当前队列中矩形的右边界小于等于其的矩形,如果高度发生变化,则写入返回变量。循环直到队列为空而且参数向量遍历完。

    刷题记录:

    1. NO BUG FREE,思路很难,要揣摩清楚。

    219. Contains Duplicate II

    Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.

    解题思路:

    1. 构建一个长度最大为k+1的集合,能够判断每个元素与其位置绝对值相差k以内的元素中是否存在重复。当长度等于k+1时,加入下一个元素之前,先把集合中位于k+1长序列开头的元素删除,即nums[i-k-1]。

    220. Contains Duplicate III

    Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.

    解题思路:

    1. 使用map结构加桶排序的思路,只需要比较当前桶内是否已经存在数,以及计算该元素与上下两个相邻桶内元素的差值是否小于要求的绝对值,如果小于则返回true。注意int类型数溢出的问题。

    221. Maximal Square

    Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.

    For example, given the following matrix:

    1 0 1 0 0
    1 0 1 1 1
    1 1 1 1 1
    1 0 0 1 0
    

    Return 4.

     
    解题思路:
    1. 此题用动态规划的方法,构建一个与原矩阵相同维度和大小的状态数组,数组每个位置上的数值代表以矩阵中对应位置为右下角所能形成的最大正方形的边的长度。
    2. i = 0 或 j = 0时,state[i][j]是否等于1取决于矩阵对应位置是否为'1',其他位置时如果matrix[i][j] = '0',显然state[i][j] = 0;如果matrix[i][j] = '1',state[i][j] = min(state[i-1][j],state[i][j-1],state[i-1][j-1])+1。

    222. Count Complete Tree Nodes

    Given a complete binary tree, count the number of nodes.

    Definition of a complete binary tree from Wikipedia:
    In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h.

    解题思路:
    1. 定义两个指针分别往左子树上移动和往右子树上移动,根据移动到NULL指针时的层数来判断当前树是否为一个满二叉树,如果是,可以直接用公式计算结点数量。否则递归调用原函数求其左子树为根结点时的结点数+其右子树为根结点时的结点数+当前的根结点1。

    223. Rectangle Area

    Find the total area covered by two rectilinear rectangles in a 2D plane.

    Each rectangle is defined by its bottom left corner and top right corner as shown in the figure.

    Rectangle Area

    Assume that the total area is never beyond the maximum possible value of int.

     
    解题思路:
    1. 一定要弄清题目表达的意思,是求两个矩形所围成的整块区域的面积,而不是求公共部分面积。因此我们可以先求公共部分的面积(如果存在),不存在则为0。然后用两个矩形的面积和减去公共部分的面积就可以得到结果,因为两个矩形的面积和将公共部分计算了两次。

    224. Basic Calculator

    Implement a basic calculator to evaluate a simple expression string.

    The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .

    You may assume that the given expression is always valid.

    Some examples:

    "1 + 1" = 2
    " 2-1 + 2 " = 3
    "(1+(4+5+2)-3)+(6+8)" = 23
    

    Note: Do not use the eval built-in library function.

    解题思路:

    1. 循环遍历字符串,根据不同类型的字符执行对应的操作就好了。1如果是' ',就继续循环。2如果是'+'或者'-',就定义一个变量记录下当前的运算符。3如果是'0'-'9'的数字,就执行内部循环,读出当前需要的操作数。4如果是'('就将之前的操作数和运算符暂存入栈中,并将当前的结果重新初始化为0,操作符初始化为'+'。5如果是')',就从栈中读取前一个操作符和之前保留的结果,与当前结果curRes进行对应的运算后赋值给当前结果。

    225. Implement Stack using Queues

    Implement the following operations of a stack using queues.

    • push(x) -- Push element x onto stack.
    • pop() -- Removes the element on top of the stack.
    • top() -- Get the top element.
    • empty() -- Return whether the stack is empty.

    Notes:

    • You must use only standard operations of a queue -- which means only push to backpeek/pop from frontsize, and is empty operations are valid.
    • Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
    • You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack).
     
    解题思路:
    1. 用队列来实现栈的存储结构,主要的难点就是队列是FIFO,而栈是FILO。所以要将栈顶元素出栈(即最后进去的元素出栈时),需要将队列里前面的元素的都出队,然后重新加入到队列的尾部,使原先的队尾元素出现在队列的头部,再将该元素出队即可。

    226. Invert Binary Tree

    Invert a binary tree.

         4
       /   
      2     7
     /    / 
    1   3 6   9

    to

         4
       /   
      7     2
     /    / 
    9   6 3   1
    解题思路:
    1. 如果当前指针为NULL,直接返回NULL即可。如果当前指针存在内容,那么将其左右指针的内容交换,然后递归调用其左右子针,转换其左右子树的指针顺序就行。

    227. Basic Calculator II

    Implement a basic calculator to evaluate a simple expression string.

    The expression string contains only non-negative integers, +-*/ operators and empty spaces . The integer division should truncate toward zero.

    You may assume that the given expression is always valid.

    Some examples:

    "3+2*2" = 7
    " 3/2 " = 1
    " 3+5 / 2 " = 5
    

    Note: Do not use the eval built-in library function.

     
    解题思路:
    1. 构造栈结构,遍历字符串,根据符号的不同选择不同的处理方式。1如果是数,就在num*10的基础上加上当前数。2如果是符号或者遍历到字符串的末尾,根据前一符号的种类执行不同的操作,如果前一符号为'+',那么直接将当前数加入栈顶即可;如果前一符号为'-',那么将当前数取负加入到栈中;如果前一符号为'*',就从栈顶读取之间的数与当前数相乘后加入栈中;如果前一符号为'/',就从栈顶读取之间的数,与当前数做除法后加入到栈顶。3如果是空格则continue。最后将栈中的所有数值加起来则为所求。

    228. Summary Ranges

    Given a sorted integer array without duplicates, return the summary of its ranges.

    For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"].

     
    解题思路:
    1. 定义两个int类型的数为start和end,分别为连续整型数列的开始与结束位置的下标index。如果当前位置上的数是前一个位置上的数+1,那么end++;反之将当前的结果写入到结果向量,并将start和end重新赋值为当前元素的下标。

    229. Majority Element II

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋times. The algorithm should run in linear time and in O(1) space.

    解题思路:
    1. 由于元素个数大于n/3的元素个数最多为2个,所以定义两个int target1和target2分别存储候选的元素,用num1和num2存储它们出现的次数。遍历数组,如果当前元素等于target1或者target2,那么将其对应的num++。如果某个元素的num=0时,相当于它和其他的元素没有区别,因此将当前元素赋值给target,并将num改写为1。只有当当前元素与两者都不相等且没有元素的num为0时,将num1和num2同时减1。
    2. 第一次遍历数组结束后,在对两个候选元素进行第二次遍历,统计它们具体在数组中出现的次数,如果大于n/3,就加入结果向量中。

    刷题记录:

    1. NO BUG FREE.

    230. Kth Smallest Element in a BST

    Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

    Note: 
    You may assume k is always valid, 1 ? k ? BST's total elements.

    Follow up:
    What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

     
     
    解题思路:
    1. 可以用中序遍历的方法。
    2. 也可以使用二分查找的方法,首先对根结点的左子树的结点数量使用迭代统计,如果k小于等于左子树结点数量,就递归调用原函数在左子树中查找;如果k大于count+1,就递归调用原函数在右子树上查找;如果k刚好等于count+1,就直接返回根结点的val值即可。

    231. Power of Two

    Given an integer, write a function to determine if it is a power of two.

     
    解题思路:
    1. 使用迭代的方法,不断的除以2,如果余数不为0,则返回false,直到商为1时跳出循环返回true。
    2. 用位运算的方法可以更方便快捷的解决这个问题,如果一个数是2的次方的话,n&(n-1)一定是为0的,因此可以直接return n > 0 && !(n&(n-1));

    232. Implement Queue using Stacks

    Implement the following operations of a queue using stacks.

    • push(x) -- Push element x to the back of queue.
    • pop() -- Removes the element from in front of queue.
    • peek() -- Get the front element.
    • empty() -- Return whether the queue is empty.

    Notes:

    • You must use only standard operations of a stack -- which means only push to toppeek/pop from topsize, and is empty operations are valid.
    • Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
    • You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).
    解题思路:
    1. 定义两个栈,一个作为输入Input,一个作为输出Output。输入中按照栈顺序存入输入元素,输出中按照队列顺序存储:具体方法如下,如果要往队列中加入元素,直接加入Input栈中即可;如果要读取栈顶元素,如果Output为空,那么循环将Input中的栈顶元素出栈并存入Output栈中,因此最先入栈Input的元素出现在输出栈的栈顶,符合队列的顺序,如果输出栈非空,就直接输出栈顶元素即可。出栈就直接将Output的栈顶元素出栈即可。

    233. Number of Digit One

    Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

    For example:
    Given n = 13,
    Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

     
    解题思路:
    1. 将目标数循环除以10来依次寻找个位、十位、百位、千位...上1的数量,直到循环商为0,依次得到的商即为该位上1的个数,还需要乘以不同的基数,个位为1,十位为10,百位为100。并且求余数,当余数大于1时说明还有一个1没有在商中算进去,同时这个1在个位、十位、百位上出现分别代表着多一个1,多10个1,多100个1;当余数小于1时,没有多余的1出现;当余数等于1时,需要加上当前的余数数量,个位为1,十位为n%10,百位为n%100。

    刷题记录:

    1. 自己独立做出来的hard题,思路与标准答案不同。明天需要把标准答案的方法弄明白,NO BUG FREE.

    234. Palindrome Linked List

    Given a singly linked list, determine if it is a palindrome.

    Follow up:
    Could you do it in O(n) time and O(1) space?

     
    解题思路:
    1. 通过slow和fast两个指针,一个一次移动一个位置,一个一次移动两个位置,同时循环找到链表中点的位置。并且将前一半的链表反转,然后从中间向两边指针遍历,比较对应位置上的值是否相等,同时将前一半的链表顺序再次反转,恢复到初始状态。
    2. 注意在链表反转的过程中需要两个指针,一个是工作指针,用来指向当前位置;一个是prev指针,用来指向它的前一个位置以便于链表反转。在初始化时将prev指针初始化为NULL,可以保持代码的一致性。

    235. Lowest Common Ancestor of a Binary Search Tree

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

    According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

            _______6______
           /              
        ___2__          ___8__
       /              /      
       0      _4       7       9
             /  
             3   5
    

    For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.

    解题思路:

    1. 寻找两个指针最近的共同祖先,需要充分利用二分查找树的特点,即左子树上的元素都是小于根结点的,右子树上的元素都是大于根结点的,因此将其各自与根结点的元素值相减乘起来,如果结果小于0,说明两个指针分布在根结点的两侧,所以最近的共同祖先就是根结点;如果等于0,说明有一个指针就是根结点,结果很显然也是根结点;如果大于0,说明两个结点分布在根结点的同一侧,递归调用子结点就可以。

    236. Lowest Common Ancestor of a Binary Tree

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

    According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”

            _______3______
           /              
        ___5__          ___1__
       /              /      
       6      _2       0       8
             /  
             7   4
    

    For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

    解题思路:

    1. 使用递归的方式去解,如果当前root为NULL或者root与p或q相等,则直接返回root;否则递归调用原函数从左子树和右子树分别查找目标指针,返回结果记作left和right,如果left和right都不为NULL,说明目标指针是分布在根结点两侧的,返回根结点;如果其中一个为NULL,那么说明这两个结点都不在当前这一侧,返回另一侧的递归结果。

    刷题记录:

    1. 递归的思路比较巧妙,NO BUG FREE

    237. Delete Node in a Linked List

    Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.

    Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function.

    解题思路:

    1. 由于我们并不知道当前指针的前一指针,所以没法直接删除当前指针。只能把next指针指向的结点的val复制到当前结点,然后将当前结点的next指向next->next。相当于删除了参数指针的next指针指向结点。

    238. Product of Array Except Self

    Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

    Solve it without division and in O(n).

    For example, given [1,2,3,4], return [24,12,8,6].

    Follow up:
    Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.)

    解题思路:
    1. 定义两个int类型的变量forward和backward,分别存储从前往后元素相乘的计算结果和从后往前相乘的结果。遍历数组,随着循环的进行,将forward和backward乘到结果向量对应的位置上,比如现在forward存储的是原数组0~i的元素的乘积结果,那么就应该将其乘入结果向量i+1的位置上,因为res[i+1]等于0~i的元素乘积与i+2~n-1的元素乘积做乘积。

    239. Sliding Window Maximum

    Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.

    For example,
    Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

    Window position                Max
    ---------------               -----
    [1  3  -1] -3  5  3  6  7       3
     1 [3  -1  -3] 5  3  6  7       3
     1  3 [-1  -3  5] 3  6  7       5
     1  3  -1 [-3  5  3] 6  7       5
     1  3  -1  -3 [5  3  6] 7       6
     1  3  -1  -3  5 [3  6  7]      7
    

    Therefore, return the max sliding window as [3,3,5,5,6,7].

    Note: 
    You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.

    Follow up:
    Could you solve it in linear time?

    解题思路:
    1. 自己的思路是定义两个优先级队列,一个window用来存储window内包含的数(可能包括window之前较小的未删除的数),一个waitdel用来存放待删除的数,如果waitdel与window的top()相同,说明未删除的元素会影响当前的最大值判断,就将其从window中删除,直到两者不相等,即待删除元素的最大值比当前window中的最大值要小,不会影响当前的最大值判断,所以可以暂时不用删除。向window中push当前位置的元素nums[i]后将最大值加入到返回向量中即可。
    2. 第二种方式是构建一个双端队列,存储窗口内元素的下标,当deque.front()<=i-k时,说明front()返回的元素下标已经处于窗口之外了,可以直接deque.pop_front();当窗口移动,需要加入元素i时,从双端队列的尾部往前,如果对应下标的元素小于等于当前元素nums[i]时,直接将其出队,此时是deque.pop_back()。因为如果新进队的元素比之前的元素要大,那么在之前的元素移出window前,新进队的元素一定都会存在在队列中,所以那么比它小的元素可以直接删除,不会影响最大值的判断。

    240. Search a 2D Matrix II

    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 in ascending from left to right.
    • Integers in each column are sorted in ascending from top to bottom.

    For example,

    Consider the following matrix:

    [
      [1,   4,  7, 11, 15],
      [2,   5,  8, 12, 19],
      [3,   6,  9, 16, 22],
      [10, 13, 14, 17, 24],
      [18, 21, 23, 26, 30]
    ]
    

    Given target = 5, return true.

    Given target = 20, return false.

    解题思路:

    1. 从matrix的左下角或者右上角开始遍历2D数组,因为针对target<,=,>matrix[row][col]有不同的处理方式,以右上角为例,如果target=matrix[row][col],直接return true;如果target<matrix[row][col],那么row++;如果target>matrix[row][col],那么col--。经过遍历的row和col是肯定不包含需要寻找的target目标数的。

    刷题记录:

    1. 刚开始尝试用二分法解题,后来发现并不适用,NO BUG FREE

    241. Different Ways to Add Parentheses

    Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +- and *.


    Example 1

    Input: "2-1-1".

    ((2-1)-1) = 0
    (2-(1-1)) = 2

    Output: [0, 2]


    Example 2

    Input: "2*3-4*5"

    (2*(3-(4*5))) = -34
    ((2*3)-(4*5)) = -14
    ((2*(3-4))*5) = -10
    (2*((3-4)*5)) = -10
    (((2*3)-4)*5) = 10

    Output: [-34, -14, -10, -10, 10]

     
    解题思路:
    1. 自己的方法是采用栈的思路,将待计算的操作符和数字都存入栈中,如果输入字符串为NULL,就将栈中的所有操作符和数进行运算直到栈中只剩下最后一个结果,就将该结果加入返回向量中;如果此时输入字符串不为NULL,就需要使用循环依次将栈中存在的内容作运算后,再将当前的符号和数字加入栈中,每次循环都会调用一次原函数计算当前情况下最后的计算结果。
    2. 答案的思路是采用递归的方法,因为每个操作符都可能作为最后一次运算,因此循环将每个操作符都作为最后一次运算涵盖了所有的情况。找到输入字符串中的操作符后,就递归调用原函数计算操作符左边和右边子字符串的运算结果组成的返回向量,然后将两个向量中的元素两两运算得到的结果加入结果向量中即可。如果不存在运算符号,说明只剩下数值,将其直接加入返回向量中。

    242. Valid Anagram

    Given two strings s and t, write a function to determine if t is an anagram of s.

    For example,
    s = "anagram", t = "nagaram", return true.
    s = "rat", t = "car", return false.

    Note:
    You may assume the string contains only lowercase alphabets.

    Follow up:
    What if the inputs contain unicode characters? How would you adapt your solution to such case?

    解题思路:
    1. 与字符串相关的问题,常常用大小为256的整型数组来记录各个字符出现的次数,因为ASCII码是用一个字节表示的,对应的整型数为0~255。当某个字符在第一个字符串中出现,就将其对应位置的统计上+1,当某个字符在第二个字符串中出现,就将其对应位置的统计-1。如果这两个字符串只是字符顺序发生了变化,那么最后字符串统计中所有的字符应该都为0,否则返回false。

    257. Binary Tree Paths

    Given a binary tree, return all root-to-leaf paths.

    For example, given the following binary tree:

       1
     /   
    2     3
     
      5
    

    All root-to-leaf paths are:

    ["1->2->5", "1->3"]
     
    解题思路:
    1. 从根结点往下递归遍历,如果当前结点为叶子结点(即左右指针都为NULL),就将当前结点加入路径中并返回;如果当前结点不是叶子结点,那么递归访问其非空的子结点。

    258. Add Digits

    Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.

    For example:

    Given num = 38, the process is like: 3 + 8 = 111 + 1 = 2. Since 2 has only one digit, return it.

    Follow up:
    Could you do it without any loop/recursion in O(1) runtime?

    解题思路:
    1. 我们可以通过对一系列数做这样的运算来寻找其中的规律,我们可以发现随着数字的增加,各位上的总和是一直在以1的速度递增的,当数字和<=9时,为单个数字直接输出;当数字和>=10时产生进位,在下一次数字相加中减少了9,比如以19举例,1+9 = 10, 1+0 = 1,相当于以9作为周期循环。但是结果是1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9...,虽说是以9作为周期循环,但是没有0的存在,所以不能直接n%9,应该将(n-1) % 9,然后再补上1,变成1 + (n-1) % 9。

    260. Single Number III

    Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

    For example:

    Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

    Note:

    1. The order of the result is not important. So in the above example, [5, 3]is also correct.
    2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
     
    解题思路:
    1. 首先将向量中所有的元素求异或,因为所有重复数的异或值为0,因此最后所得结果为目标元素的异或值diff。diff上为'0'的地方为两个目标数相同的地方,为'1'的bit位为两个目标数不同的位置,即在那些bit位,一个为'0',一个为'1',根据这个就可以将两个目标数区分开。由于只需要1位做区分,所有我们找到最低不同位为'1',其余位置为0,即diff &= -diff。
    2. 在第二次的遍历中就可以将两个数划分开了,如果我们作为判定位的数为'1',即nums[i] & diff != 0,就与第一个返回数res[0]相异或;如果判定位的数为'0',即nums[i] & diff == 0,就与第二个返回数res[1]相异或。

    刷题记录:

    1. 思路很奇妙,NO BUG FREE.

    263. Ugly Number

    Write a program to check whether a given number is an ugly number.

    Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7.

    Note that 1 is typically treated as an ugly number.

     
    解题思路:
    1. 如果参数小于1返回false,如果参数大于1且除以2,3,5的余数都不为0,返回false,否则除以使其余数为0的因子,直到结果为1,说明其因子仅由2,3,5组成,返回true。

    264. Ugly Number II

    Write a program to find the n-th ugly number.

    Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10ugly numbers.

    Note that 1 is typically treated as an ugly number, and n does not exceed 1690.

     
    解题思路:
    1. 定义3个int型变量pos2,pos3和pos5分别用来存储未乘以2,3,5因子的最小数位置。在每次循环中比较这三者对应位置的元素与其因子相乘的结果,取最小值放置到数组的当前位置中。如果最小值与nums[pos2] * 2相同,pos2++;如果最小值与nums[pos3] * 3相同,pos3++;如果最小值与nums[pos5] * 5相同,pos5++。必须分别判断,因此存在某个最小值等于两者的情况,比如6 = 2*3 = 3*2。

    268. Missing Number

    Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.

    For example,
    Given nums = [0, 1, 3] return 2.

    Note:
    Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?

     
    解题思路:
    1. 有两种思路解此题,第一种是从0~n的叠加公式我们知道,因此可以计算出其总和,然后减去给的参数向量中元素的总和,差值就是缺失元素。
    2. 使用位操作运算符^来实现,将向量中所有的数以及从0~n的下标异或,如果对应下标和数都存在的话,两者的异或为0,单独存在一个,异或的结果就是那个数。

    273. Integer to English Words

    Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 1.

    For example,

    123 -> "One Hundred Twenty Three"
    12345 -> "Twelve Thousand Three Hundred Forty Five"
    1234567 -> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"

    解题思路:

    1. 定义map<int, string>结构,将需要的数字和单词联系起来。注意细节的分析和代码的一致性即可。

    274. H-Index

    Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index.

    According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each."

    For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at least 3 citations each and the remaining two with no more than 3 citations each, his h-index is 3.

    Note: If there are several possible values for h, the maximum one is taken as the h-index.

    Credits:
    Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.

     
    解题思路:
    1. 首先使用对元素排序的方式,时间复杂度为O(nlgn),空间复杂度为O(1)。排序后从前往后遍历元素,当元素大小>=当前位置之后所剩元素个数,因为后面的元素都比它大,因此大于len-i的元素个数至少为len-i,返回当前的len-i。
    2. 答案中使用的方法类似于桶排序,时间复杂度为O(n),空间复杂度也为O(n)。定义一个长度为len+1的向量,分别用来存储相应引用数的文章个数,当引用数>=len时,都将bucket[len]++,因为返回值最多为len。从后往前遍历bucket向量,当积累的论文篇数>=当前的下标(也即是引用数)时,返回当前引用。

    275. H-Index II

    Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimize your algorithm?

    解题思路:

    1. 针对排序数组的问题,一定要想到二分法。根据citations[mid]与citations.size()-mid的大小关系来对low和high进行更改。如果citations[mid] >= citations.size(),那么mid就有可能是最后的结果,但是还要考虑是否有更大的情况,因此high = mid;如果citations[mid] < citations.size(),那么就需要降低要求,low = mid+1。循环直到low = high为止,最后return citations[high] >= citations.size() - high ? citations.size() - high : 0。

    278. First Bad Version

    You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.

    Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad.

    You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

     
    解题思路:
    1. 用二分法可以解决这个问题。需要注意的是,我们平常写的一般是int mid = (low + high)/2;当low和high都比较大时,它们俩的和就可能会发生溢出,此时需要将其改写为int mid = low + (high - low) / 2;更加安全。

    279. Perfect Squares

    Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

    For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.

     
    解题思路:
    1. 使用动态规划的方法依次求1~n的最小数量。这样可以最大程度的避免重复计算,for(int j = 1; j * j <= n; j++)  nums[n] = min(nums[n], 1+nums[n-j*j])。如上所示,如果要求和为n的最小平方数的数目,就是用当前数减去可能的平方数,然后差的最小平方数+1,取各种可能中最小的作为当前数的最小平方数求和数目。

    刷题记录:

    1. 动态规划的经典问题,思路很神奇,NO BUG FREE.

    282. Expression Add Operators

    Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators (not unary) +-, or * between the digits so they evaluate to the target value.

    Examples: 

    "123", 6 -> ["1+2+3", "1*2*3"] 
    "232", 8 -> ["2*3+2", "2+3*2"]
    "105", 5 -> ["1*0+5","10-5"]
    "00", 0 -> ["0+0", "0-0", "0*0"]
    "3456237490", 9191 -> []
    
     
    解题思路:
    1. 此题没有什么太多的技巧,就是通过递归的方式,将所有可能的情况列举出来,比较表达式的结果和目标数是否一致,如果一致则加入返回向量中。主要是对两种形式下的不同可能进行分类和递归调用,首先是从当前位置出发所转换成的数的长度有差别,可以从当前位置一直延续到字符串尾部;其次是当前数与之前的表达式之间的连接符号有三种可能,分别是'+','-'和'*'。
    2. 要注意计算当前值上存在差异,如果当前数之间加入的符号是'+'或者'-'直接用之前的结果加上或减去当前数即可。但是如果当前的符号加入的是'*',就会存在一些变化,首先原本加上或减去的数不应该加上或减去了,其次需要将上一个数乘以当前数后再加上或减去,所以我们需要定义一个参数用来记录之前加上或减去的数prev,如果当前符号为'*',就用result - prev + prev * cur,并且更新prev(即prev * cur)。

    刷题记录:

    1. NO BUG FREE.

    283. Move Zeroes

    Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.

    For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].

    Note:

    1. You must do this in-place without making a copy of the array.
    2. Minimize the total number of operations.
     
    解题思路:
    1. 定义一个整型的zero_flag用来指示数组中非零元素的个数,也是下一个非零元素所需要存入的位置,每遍历到一个非零元素,就将其写入,并且zero_flag++。直到遍历完数组,将所有非零元素都按照原有的顺序移到数组的前面。再将zero_flag及其之后位置上的元素写为0。

    284. Peeking Iterator

    Given an Iterator class interface with methods: next() and hasNext(), design and implement a PeekingIterator that support the peek() operation -- it essentially peek() at the element that will be returned by the next call to next().


    Here is an example. Assume that the iterator is initialized to the beginning of the list: [1, 2, 3].

    Call next() gets you 1, the first element in the list.

    Now you call peek() and it returns 2, the next element. Calling next() after that still return 2.

    You call next() the final time and it returns 3, the last element. Calling hasNext() after that should return false.

    Follow up: How would you extend your design to be generic and work with all types, not just integer?

     
    解题思路:
    1. 利用派生类对象的特点来做。主要包括用this指针进行初始化赋值以及调用基类对象的成员函数。

    287. Find the Duplicate Number

    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

    Note:

    1. You must not modify the array (assume the array is read only).
    2. You must use only constant, O(1) extra space.
    3. Your runtime complexity should be less than O(n2).
    4. There is only one duplicate number in the array, but it could be repeated more than once.
    解题思路:
    1. 可以把该题转化为类似于之前的链表存在循环的问题,根据value值遍历数组,如果访问的结点都是不存在重复的结点,那么下次会访问到一个新的未曾访问过的结点,直到没有访问的结点越来越少,最后一定会访问到之前重复的结点,进入一个循环。
    2. 定义一个每次往后一个结点的int型slow和一个每次往后2个的fast,fast会率先进入循环内,直到slow也进去循环内与其相遇。此时将slow改写为0,两个Index都以每次一格的速度往后,最后相遇的结点index就是循环的入口也就是重复的数值。

    刷题记录:

    1. 思路很奇妙,NO BUG FREE

    289. Game of Life

    According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970."

    Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):

    1. Any live cell with fewer than two live neighbors dies, as if caused by under-population.
    2. Any live cell with two or three live neighbors lives on to the next generation.
    3. Any live cell with more than three live neighbors dies, as if by over-population..
    4. Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.

    Write a function to compute the next state (after one update) of the board given its current state.

    Follow up: 

    1. Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells.
    2. In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems?
    解题思路:
    1. 由于只能在in-place进行操作,但是每个细胞下一代的状态依赖与其周围细胞前一时刻的状态。所以我们要想办法不仅将细胞下一代的状态保存,还要保存其前一代的状态。使用两个bit进行存储,最后一个bit用于存储其前一代的状态,倒数第二个bit用来存储其下一代的状态。一共有四种情况为:00,01,10,11。
    2. 在计算前一代细胞周围活着的细胞数量时,使用board[i][j] & 1读取最后一个bit的值,然后结合细胞当前的状态,写入其下一状态。全部循环完后再次循环将上一代状态移出,只剩下当前状态。

    290. Word Pattern

    Given a pattern and a string str, find if str follows the same pattern.

    Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.

    Examples:

    1. pattern = "abba", str = "dog cat cat dog" should return true.
    2. pattern = "abba", str = "dog cat cat fish" should return false.
    3. pattern = "aaaa", str = "dog cat cat dog" should return false.
    4. pattern = "abba", str = "dog dog dog dog" should return false.

    Notes:
    You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.

    解题思路:
    1. 使用istringstream字符串输入流可以很方便的完成由空格分隔字符串的单词的读入。单词和字母是一一对应的情况,并不一定非得你对应我,我对应你,只要它们俩对应的是同一个整型数也能达到同样的效果。

    292. Nim Game

    You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.

    Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.

    For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.

     
    解题思路:
    1. 本题的关键在于寻找游戏中所蕴含的规律。如果n<=3,我一定赢;如果n = 4,我无法一次拿完,而且我拿剩下之后,对方一定能拿完,所以我一定输;5 <= n <= 7,我一次可以拿到只剩下4,所以对方一定输;n = 8,我拿一次之后,对方一定能剩下4给我拿,所以我一定输;9 <= n <=11,我拿一次后一定能剩下8给对面,所以对方一定输。以此类推。
    2. 所有能被4整除的n一定输,其他一定赢。

    295. Find Median from Data Stream

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.

    Examples: 

    [2,3,4] , the median is 3

    [2,3], the median is (2 + 3) / 2 = 2.5

    Design a data structure that supports the following two operations:

    • void addNum(int num) - Add a integer number from the data stream to the data structure.
    • double findMedian() - Return the median of all elements so far.

    For example:

    addNum(1)
    addNum(2)
    findMedian() -> 1.5
    addNum(3) 
    findMedian() -> 2
    
     
    解题思路:
    1. 如果想要插入数,或者使用到堆排序(大根堆,小根堆)的特性,我们就使用优先级队列的数据结构,priority_queue实际上就是一种堆排序。通过定义结构体比较函数,我们可以自定义优先级顺序,当返回bool类型为true时,后者的优先级较高,排在队列的前面。
    2. 本题中定义两个优先级队列,分别存储前半部分由大到小和后半部分由小到大。两者的队头元素,即为中间值。在执行过程中,每当插入一个数,先放置到minor(较小部分)的队列中(过滤一下),再将minor中最大的元素放置到较大部分的队列。再调整两边size的大小,保证顺序的一致性。

    297. Serialize and Deserialize Binary Tree

    Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

    Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

    For example, you may serialize the following tree

        1
       / 
      2   3
         / 
        4   5
    

    as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.

     
    解题思路:
    1. 使用带有空结点标识的前序遍历来做,先向输出流中输出当前根结点的val值,然后递归调用其左子树和右子树结点,如果结果为空,就向流中输出"#"作为标识。
    2. 在重构二叉树的过程中,如果当前输入流为"#",就返回NULL,如果为val值,则new一个指针指向新的根结点,然后递归重构其左子树和右子树。

    刷题记录:

    1. 思路很重要,NO BUG FREE

    299. Bulls and Cows

    You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive the secret number.

    For example:

    Secret number:  "1807"
    Friend's guess: "7810"
    

    Hint: 1 bull and 3 cows. (The bull is 8, the cows are 01 and 7.)

    Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. In the above example, your function should return "1A3B".

    Please note that both secret number and friend's guess may contain duplicate digits, for example:

    Secret number:  "1123"
    Friend's guess: "0111"
    

    In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B".

    You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal.

     
    刷题记录:
    1. 定义两个整型变量分别存储bull和cow的数量,用一个大小为10的数组来存储10个数字出现的数量,secret串中出现的字符对数组的贡献是对应位置加1,guess串中出现的字符对数组的贡献是对应位置减1。如果secret串中当前字符对应的数量<0,说明guess串存在空余的当前字符,cow++;如果guess串中当前字符对应的数量>0,说明secret串中存在空余的当前字符,cow++。那么遍历两个字符串,如果当前位置的数字相同,则bull++;如果不同,则按照前面叙述的执行即可。

    300. Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence.

    For example,
    Given [10, 9, 2, 5, 3, 7, 101, 18],
    The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. Note that there may be more than one LIS combination, it is only necessary for you to return the length.

    Your algorithm should run in O(n2) complexity.

    Follow up: Could you improve it to O(n log n) time complexity?

     
    解题思路:
    1. 简单的动态规划是,当遍历到位置i上的数时,就将该数与之前所有的数做比较,如果大于之前的某个数j,那么最长距离length[i] = max(length[i], length[j]+1)。时间复杂度为O(n^2)。
    2. 更好的动态规划是定义一个数组tail用来存储之前已经出现过的数列中,不同长度的最小尾数,显然tail随着下标也就是长度的增加,是一个递增序列,因此我们可以用二分法解决这个问题。当循环遍历到i时,我们用二分法将nums[i]与已经存在的tail进行比较,找到nums[i]在tail数组中的位置,如果tail[low] < nums[i] <= tail[low+1],那么就修改tail[low+1]的值;如果nums[i] > tail[size],即大于当前最大长度的tail,就得到了新的长度,向数组中push nums[i]作为新的长度递增序列的结尾,并将maxlength++。

     

  • 相关阅读:
    吉特仓储管系统(开源WMS)--分享两月如何做到10W+的项目
    吉特仓库管理系统(开源)-如何在网页端启动WinForm 程序
    RequireJS中的require如何返回模块
    RequireJS shim 用法说明
    从ISTIO熔断说起-轻舟网关熔断
    数据库与数据仓库的区别是什么
    API是什么
    要想业务中台建得快,最好用Service Mesh来带
    中台建设之路-中台建设怎么做?建设中台需要具备什么?
    为什么要建设中台
  • 原文地址:https://www.cnblogs.com/hopelee/p/6636835.html
Copyright © 2011-2022 走看看