[关闭]
@chanvee 2014-12-14T11:29:58.000000Z 字数 7687 阅读 6105

LeetCode 题解二(python版)

LeetCode, Python


Same Tree


这个题的意思非常简单,给定两颗二叉树,判断这两颗二叉树是否相同。树相同包括两点:一是结构相同,而是值相同。因此我们只需要对两棵树同时遍历)(简单的递归)一遍,遇到不同(结构不同或者值不同)时则返回False;若遍历一遍之后没有发现不同则说明这两棵树相同。代码如下:

  1. # Definition for a binary tree node
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. # @param p, a tree node
  9. # @param q, a tree node
  10. # @return a boolean
  11. def isSameTree(self, p, q):
  12. if p == None and q == None:
  13. return(True)
  14. elif p == None or q == None:
  15. return(False)
  16. else:
  17. if p.val != q.val:
  18. return(False)
  19. else:
  20. if self.isSameTree(p.left, q.left):
  21. return(self.isSameTree(p.right, q.right))
  22. else:
  23. return(False)

Symmetric Tree


这个题是判断一棵树是不是对称树。我们可以根据上一个题来解决这个问题,先给代码:

  1. # Definition for a binary tree node
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. # @param root, a tree node
  9. # @return a boolean
  10. def isSymmetric(self, root):
  11. if root == None:
  12. return(True)
  13. else:
  14. return(self.isSameTree(root.left, root.right))
  15. def isSameTree(self, p, q):
  16. if p == None and q == None:
  17. return(True)
  18. elif p == None or q == None:
  19. return(False)
  20. else:
  21. if p.val != q.val:
  22. return(False)
  23. else:
  24. if self.isSameTree(p.left, q.right):
  25. return(self.isSameTree(p.right, q.left))
  26. else:
  27. return(False)

有代码可知,我们首先把这个树分成左右两颗子树,然后遍历这两颗子树,比较时不再是左边和左边的比,因为对称,所以比较左子树的左节点和右子树的右节点以及左子树的右节点和右子树的左节点是否相等即可。

Add Two Numbers


这个题目是实现链表的加法,刚开始理解错了,看到题目给的例子以为给的两个列表长度是相等的,其实不是哈,不一定等长。题目本身很简单,值得一提的是python中链表的操作,才开始我硬是没搞清楚,先贴代码:

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. class Solution:
  7. # @return a ListNode
  8. def addTwoNumbers(self, l1, l2):
  9. add = 0
  10. l3 = ListNode(0)
  11. cur = l3
  12. while l1 or l2:
  13. node = ListNode(add)
  14. if l1:
  15. node.val += l1.val
  16. l1 = l1.next
  17. if l2:
  18. node.val += l2.val
  19. l2 = l2.next
  20. if node.val >= 10:
  21. add = 1
  22. else:
  23. add = 0
  24. node.val %= 10
  25. cur.next, cur = node, node
  26. if add:
  27. cur.next = ListNode(1)
  28. return(l3.next)

代码中·cur = l3,表示cur和l3都指向了同一个链表,在另一句cur.next, cur = node, node中,当第一次执行这句话时,首先cur.next指向了node,也代表了l3.next也指向了node,然后cur再指向node,也就是指向了l3的next;当再一次执行时,首先cur.next指向node就相当于l3.next.next指向node,以此类推,从而cur就相当于实现了C中的指针的作用了。

Remove Duplicates from Sorted List


这个题目的意思是去除掉链表中所有重复的元素,即每个元素只保留一次,方法就是遍历这个链表,每次将当前节点的值跟下一个的节点的值相比,如果相同则将当前节点指向下下个节点即可,需要注意的是如果下下个节点没有的话,则当前节点指向None。代码如下:

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. class Solution:
  7. # @param head, a ListNode
  8. # @return a ListNode
  9. def deleteDuplicates(self, head):
  10. if head == None:
  11. return(None)
  12. else:
  13. cur = ListNode(head.val)
  14. cur.next, head = head, cur
  15. while cur:
  16. if cur.next and cur.val == cur.next.val:
  17. if cur.next.next:
  18. cur.next = cur.next.next
  19. else:
  20. cur.next = None
  21. else:
  22. cur = cur.next
  23. return(head)

Remove Duplicates from Sorted List II


这个题是上一个题目的升级版,只要出现重复的数字,这些数字都要从链表中删掉,方法是在链表前先加一个节点以及一个删除标识,然后遍历这个链表,比较后两个节点是否相同,如果相同,先删掉第一个节点,并让删除标识变为真,表明下一次操作需要把第二个节点删掉(即使下一次比较的时候两个节点值不同,但是上次只删掉了一个重复节点,所以还是要把它删掉),如果下两个节点不同且删除标识不为真则跳过。代码如下:

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. class Solution:
  7. # @param head, a ListNode
  8. # @return a ListNode
  9. def deleteDuplicates(self, head):
  10. if head == None or head.next == None:
  11. return(head)
  12. cur = ListNode(head.val)
  13. cur.next, head = head, cur
  14. flag = False
  15. while cur:
  16. if cur.next and cur.next.next and cur.next.val == cur.next.next.val:
  17. cur.next = cur.next.next
  18. flag = True
  19. elif flag and cur.next:
  20. cur.next = cur.next.next
  21. flag = False
  22. else:
  23. cur = cur.next
  24. return(head.next)

Remove Duplicates from Sorted Array


这个题与上面两个题类似,只是有链表变为了指针,需要注意的是虽然题目只要求返回数组的长度,但是它还有一个隐性的要求就是要使得数组A[0:len]是你想要的得到的不包含重复元素的数组,如他给的例子A=[1,1,2],remove 完之后要求A=[1,2,2],也就是说A[0:2] = [1,2]。我就在这里卡了好久。。。代码如下:

  1. class Solution:
  2. # @param a list of integers
  3. # @return an integer
  4. def removeDuplicates(self, A):
  5. if A == []:
  6. return(0)
  7. count = 1
  8. for i in range(1,len(A)):
  9. if A[i] != A[i-1]:
  10. A[count] = A[i]
  11. count += 1
  12. return(count)

Remove Duplicates from Sorted Array II


这个题是上个题目的升级版,这是移除数组中重复元素大于2个的元素并返回新数组的长度,思想类似,这里就不在赘述,直接贴代码:

  1. class Solution:
  2. # @param A a list of integers
  3. # @return an integer
  4. def removeDuplicates(self, A):
  5. if len(A) <= 2:
  6. return(len(A))
  7. count = 2
  8. for i in range(2,len(A)):
  9. if A[i] != A[count-1] or A[i] != A[count-2]:
  10. A[count] = A[i]
  11. count += 1
  12. return(count)

Pascal's Triangle


题目的意思是生成n行的Pascal's三角并存入到列表中。思路是第i(i>=3)的第j个元素等于第i-1行的第j-1个元素和第j个元素之和,初识化第一二行之后for一下就可以了,另外由于Pascal's三角是对称的,所以我们每次只需算前一半即可。代码如下:

  1. class Solution:
  2. # @return a list of lists of integers
  3. def generate(self, numRows):
  4. if numRows == 1:
  5. return([[1]])
  6. elif numRows == 2:
  7. return([[1],[1,1]])
  8. elif numRows == 0:
  9. return([])
  10. else:
  11. result = [[1],[1,1]]
  12. for i in range(3, numRows+1):
  13. tmp = [1]*i
  14. last = result[i-2]
  15. for j in range(1,(i-1)//2 + 1):
  16. tmp[j] = tmp[i-1-j] = last[j-1] +last[j]
  17. result.append(tmp)
  18. return(result)

Pascal's Triangle II


这个题跟上一个题目类似,只是这次不是全部返回,而是只返回固定的某一行。由于Pascal's三角中的第i行第j个元素

L(i,j)=Cj1i=i!(j1)!(nj+1)!
,所有我们就可以很简单得到任意一行的值了,只需再添加一个计算阶乘的函数,代码如下:

  1. class Solution:
  2. # @return a list of integers
  3. def getRow(self, rowIndex):
  4. result = [1]*(rowIndex + 1)
  5. for i in range(1,(rowIndex)//2 + 1):
  6. result[i] = result[rowIndex-i] = self.factorial(rowIndex)//(self.factorial(i)*self.factorial(rowIndex-i))
  7. return(result)
  8. def factorial(self, n):
  9. if n == 1:
  10. return(1)
  11. else:
  12. return(n*self.factorial(n-1))

Minimum Depth of Binary Tree


这个题目是计算一颗二叉树的最小深度,分别计算左右子树的深度,然后取较小,深度的计算方法是如果节点是叶子节点深度加1,如果节点有子节点深度加1,初识化左右子树深度为无穷大。代码如下:

  1. # Definition for a binary tree node
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. # @param root, a tree node
  9. # @return an integer
  10. def minDepth(self, root):
  11. if root == None:
  12. return(0)
  13. if root.left == None and root.right == None:
  14. return(1)
  15. left = right = float("inf") # 表示无穷大
  16. if root.left != None:
  17. left = 1 + self.minDepth(root.left)
  18. if root.right != None:
  19. right = 1 + self.minDepth(root.right)
  20. return(min(left, right))

Maximum Depth of Binary Tree


与上题类似,只不过是找树的最大深度,改一下判别条件就可以了。代码如下:

  1. # Definition for a binary tree node
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. # @param root, a tree node
  9. # @return an integer
  10. def maxDepth(self, root):
  11. if root == None:
  12. return(0)
  13. if root.left == None and root.right == None:
  14. return(1)
  15. left = right = -1
  16. if root.left != None:
  17. left = 1 + self.maxDepth(root.left)
  18. if root.right != None:
  19. right = 1 + self.maxDepth(root.right)
  20. return(max(left, right))

Path Sum


这个题的意思是一颗二叉树上是否存在一条从根节点到叶子节点的路径,其上所有节点之和等于一个指定的数。方法就是当我们从根节点往下递归时,看当前节点是否存在sum减去前面节点之和的路径存在。代码如下:

  1. # Definition for a binary tree node
  2. # class TreeNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.left = None
  6. # self.right = None
  7. class Solution:
  8. # @param root, a tree node
  9. # @param sum, an integer
  10. # @return a boolean
  11. def hasPathSum(self, root, sum):
  12. result = False
  13. if root == None:
  14. return(result)
  15. else:
  16. sum -= root.val
  17. if sum == 0 and root.left == None and root.right == None:
  18. result = True
  19. return(result)
  20. else:
  21. if root.left:
  22. result = result or self.hasPathSum(root.left, sum) # 只要存在一条就返回True
  23. if root.right:
  24. result = result or self.hasPathSum(root.right, sum)
  25. return(result)

Length of Last Word


求一行字符串中最后一个单词的长度,这个题用python做就非常简单了,代码如下:

  1. class Solution:
  2. # @param s, a string
  3. # @return an integer
  4. def lengthOfLastWord(self, s):
  5. if s == '':
  6. return(0)
  7. result = s.split()
  8. if result == []:
  9. return(0)
  10. return(len(result[-1]))

Add Binary


这个题目非常简单,就是二进制的加法。对于我们这种python的初学者来说难点是字符串与列表的转化,题目本身需要注意的一个地方就是,最后可能由于进位需要补一位,我们可以先把字符串先倒一转再加,这样就可以在末尾补位。代码如下:

  1. class Solution:
  2. # @param a, a string
  3. # @param b, a string
  4. # @return a string
  5. def addBinary(self, a, b):
  6. a = a[::-1] # 字符串倒序
  7. b = b[::-1] # 字符串倒序
  8. i = j = 0
  9. c = []
  10. add = 0 # 表示进位
  11. while i < len(a) or j < len(b):
  12. if i < len(a) and j < len(b):
  13. tmp = (int(a[i]) + int(b[j]) + add) % 2
  14. c.append(str(tmp))
  15. if (int(a[i]) + int(b[j]) + add) >= 2:
  16. add = 1
  17. else:
  18. add = 0
  19. i += 1
  20. j += 1
  21. if i < len(a) and j>= len(b):
  22. tmp = (int(a[i]) + add)%2
  23. c.append(str(tmp))
  24. if (int(a[i]) + add) >= 2:
  25. add = 1
  26. else:
  27. add = 0
  28. i += 1
  29. if i >= len(a) and j < len(b):
  30. tmp = (int(b[j]) + add)%2
  31. c.append(str(tmp))
  32. if (int(b[j]) + add) >= 2:
  33. add = 1
  34. else:
  35. add = 0
  36. j += 1
  37. if add:
  38. c.append('1')
  39. c = c[::-1]
  40. result = "".join(c)
  41. return(result)

Valid Parentheses


这道题是判断括号是否匹配,就是利用栈来进行解决,遇到正括号加入栈,遇到反括号弹出栈看是否匹配,只不过刚开始时可以直接排除一些结果:1)如果字符串的长度为奇数,必然False;2)如果最后一个字符是‘(’‘[’‘{’,必然false;3)第一个字符为‘)’‘]’‘}’必然False等。代码如下:

  1. class Solution:
  2. # @return a boolean
  3. def isValid(self, s):
  4. if len(s)%2 != 0 or s[-1] == '(' or s[-1] =='[' or s[-1] =='{':
  5. return(False)
  6. result = True
  7. a = []
  8. for i in range(len(s)):
  9. if s[i] =='(' or s[i] =='[' or s[i] =='{':
  10. a.append(s[i])
  11. else:
  12. if len(a) == 0:
  13. result = False
  14. break
  15. if s[i] == ')':
  16. if a.pop() != '(':
  17. result = False
  18. break
  19. if s[i] == ']':
  20. if a.pop() != '[':
  21. result = False
  22. break
  23. if s[i] == '}':
  24. if a.pop() != '{':
  25. result = False
  26. break
  27. return(result)
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注