最长回文子串 最长回文子串 
解题思路 
中心扩展算法 ,从每个位置出发,向两边扩展 ,若遇到的是回文子串,就继续扩展;若不是回文子串就结束,到下一个位置去。扩展方法:
向左扩展 ,向左寻找与当前位置相同的字符,直到遇到不等的字符为止 
向右扩展 ,向右扩展,向右寻找与当前位置相同的字符,直到遇到不等的字符为止 
左右双向扩展 ,同时向左右扩展,直到遇到左右字符不等为止 
 
 
动态规划 法,用dp[i][j]表示字符串s从第i个字符到第j个字符是否未回文子串(true表示是回文子串,false表示不是回文子串)。
则状态转移方程 为dp[i][j] = dp[i+1][j-1] ^ (s[i] == s[j]) 
边界条件
只有一个字符时,肯定是回文子串dp[i][i] = true 
只有两个字符时,只要两个字符相等就一定是回文子串dp[i][i+1] = (s[i] == s[i+1]) 
 
 
 
 
 
 
解题代码 
中心扩展法 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 func  longestPalindrome (s string )  string   {    len  := len (s)        var  left, right int       var  maxStart, maxLen int          for  i := 0 ; i < len ; i++ {         curLen := 1              for  left = i-1 ; left >= 0  && s[left] == s[i]; left-- {                          curLen++         }         for  right = i+1 ; right < len  && s[right] == s[i]; right++ {                          curLen++         }         for  left >= 0  && right < len  {                          if  s[left] != s[right] {                 break              }             left--             right++             curLen+=2          }         if  curLen > maxLen {             maxLen = curLen             maxStart = left+1          }     }     return  s[maxStart:maxStart + maxLen] } 
 
动态规划 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 func  longestPalindrome (s string )  string   {    len  := len (s)        if  len  < 2  {                  return  s     }     var  maxStart int          maxLen := 1                dp := make ([][]bool , len )     for  i := 0 ; i < len ; i++ {         dp[i] = make ([]bool , len )              }     for  j := 1 ; j < len ; j++ {         for  i := 0 ; i < j; i++ {             if  s[i] == s[j] && (j-i <= 2  || dp[i+1 ][j-1 ] == true ) {                                                   dp[i][j] = true                  if  j-i+1  > maxLen {                     maxStart = i                     maxLen = j-i+1                  }             }         }     }     return  s[maxStart:maxStart+maxLen] } 
 
合并K个排序链表 合并K个排序链表 
解题思路 
暴力法,根据归并 的思想,每次选取排序链表组中值最小 的节点加入到结果链表中
 
顺序合并 ,对于两个有序链表的合并是简单的,那么可以逐一合并各个链表,第i次合并第i个链表
 
分治合并 ,对方法2进行优化,不对其进行顺序合并,而是两两合并 。
若有k个链表,第一轮合并k/2组链表,每一组时间代价是O(2n) 
第二轮合并k/4组链表,每一组时间代价O(4n) 
以此类推,最后剩下一个链表即为结果 
 
 
 
解题代码 
暴力归并 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 func  mergeKLists (lists []*ListNode)  *ListNode   {    newHead := &ListNode{}       rear := newHead      p := make ([]*ListNode, len (lists))       for  i := 0 ; i < len (lists); i++ {         p[i] = lists[i]     }     var  overNum int       for  overNum <= len (lists)-1  {                   min := p[0 ]         minIndex := 0             for  i := 0 ; i < len (lists); i++ {             if  min == nil  || (p[i] != nil  && p[i].Val < min.Val) {                 min = p[i]                 minIndex = i             }         }         if  min == nil  {             break          }         p[minIndex] = p[minIndex].Next                 if  p[minIndex] == nil  {                          overNum++         }         rear.Next = min             rear = rear.Next             rear.Next = nil           }               for  i := 0 ; i < len (p); i++ {         if  p[i] != nil  {             rear.Next = p[i]             break          }     }     return  newHead.Next } 
 
顺序合并 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 func  mergeKLists (lists []*ListNode)  *ListNode   {    if  len (lists) == 0  {         return  nil      }     res := lists[0 ]     for  i := 1 ; i < len (lists); i++ {         res = mergeList(res, lists[i])     }     return  res } func  mergeList (l1, l2 *ListNode)  *ListNode   {        newHead := &ListNode{}       rear := newHead      p, q := l1, l2       for  p!= nil  && q != nil  {                  if  p.Val < q.Val {             rear.Next = p             p = p.Next             rear = rear.Next             rear.Next = nil          } else  {             rear.Next = q             q = q.Next             rear = rear.Next             rear.Next = nil          }     }          if  p != nil  {         rear.Next = p     }     if  q != nil  {         rear.Next = q     }     return  newHead.Next  } 
 
分治合并 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 func  mergeKLists (lists []*ListNode)  *ListNode   {    k := len (lists)       if  k == 0  {         return  nil      }     for  k > 1  {          newLists := make ([]*ListNode, 0 )         k = 0          for  i := 0 ; i < len (lists); i+=2  {             if  i != len (lists)-1  {                                  newLists = append (newLists, mergeList(lists[i], lists[i+1 ]))                 k++             } else  {                                  newLists = append (newLists, lists[i])                 k++             }         }         lists = newLists     }     return  lists[0 ] } func  mergeList (l1, l2 *ListNode)  *ListNode   {        newHead := &ListNode{}       rear := newHead      p, q := l1, l2       for  p!= nil  && q != nil  {                  if  p.Val < q.Val {             rear.Next = p             p = p.Next             rear = rear.Next             rear.Next = nil          } else  {             rear.Next = q             q = q.Next             rear = rear.Next             rear.Next = nil          }     }          if  p != nil  {         rear.Next = p     }     if  q != nil  {         rear.Next = q     }     return  newHead.Next  } 
 
合并区间 合并区间 
解题思路 首先对区间的左端点进行排序 ,那么在排完序的列表中,可以合并的区间一定是连续的 。将第一个区间加入结果res中,并且按顺序考虑每个区间:
若当前区间与结果集的最后一个区间不相交,那么将当前区间加入到结果集中 
若当前区间与结果集的最后一个区间相交,那么进一步考虑若当前的右端点在结果集的最后一个区间的右端点的右侧,则更新结果集中最后一个区间的右端点 
 
解题代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 type  ints [][]int func  merge (intervals [][]int )  [][]int   {    if  len (intervals) == 0  {         return  nil      }          ints := ints(intervals)     sort.Sort(ints)     intervals = [][]int (ints)          res := [][]int {intervals[0 ]}     for  i := 1 ; i < len (intervals); i++ {         if  intervals[i][0 ] > res[len (res)-1 ][1 ] {                          res = append (res, intervals[i])         } else  {                          if  intervals[i][1 ] > res[len (res)-1 ][1 ] {                                  res[len (res)-1 ][1 ] = intervals[i][1 ]             }         }     }     return  res } func  (this ints)  Len ()  int   {    return  len (this) } func  (this ints)  Less (i, j int )  bool   {    if  this[i][0 ] < this[j][0 ] {         return  true      } else  {         return  false      } } func   (this ints)  Swap (i, j int )   {    this[i], this[j] = this[j], this[i] } 
 
二叉树的最大高读 二叉树的最大深度 
解题思路 基于二叉树的后续遍历,首先得到左子树高度left,右子树高度right,二叉树高度为1 + max(left, right)
解题代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 func  maxDepth (root *TreeNode)  int   {    var  postorder func (root *TreeNode)  int      postorder = func (root *TreeNode)  int   {         if  root != nil  {             left := postorder(root.Left)              right := postorder(root.Right)                return  1  + max(left, right)         } else  {                          return  0          }     }     return  postorder(root) } func  max (n1, n2 int )  int   {    if  n1 > n2 {         return  n1     } else  {         return  n2     } } 
 
平衡二叉树 平衡二叉树 
解题思路 若left为左子树高度,right为右子树高度,若|left - right| <= 1 && 左子树为平衡二叉树 && 右子树为平衡二叉树,则这棵树就是平衡二叉树
解题代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 func  isBalanced (root *TreeNode)  bool   {    if  root != nil  {         left := height(root.Left)            right := height(root.Right)          return  abs(left-right) <= 1  && isBalanced(root.Left) && isBalanced(root.Right)     } else  {                  return  true      }      } func  height (root *TreeNode)  int   {    if  root != nil  {         left := height(root.Left)          right := height(root.Right)            return  1  + max(left, right)     } else  {                  return  0      } } func  max (n1, n2 int )  int   {    if  n1 > n2 {         return  n1     } else  {         return  n2     } } func  abs (n int )  int   {    if  n >= 0  {         return  n     } else  {         return  -n     } }