[刷题] Leetcode算法 (2020-3-1)
1.删除排序链表中的重复元素
题目:
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例:
输入: 1->1->2->3->3 输出: 1->2->3
代码:
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def deleteDuplicates(self, head: ListNode) -> ListNode: # 如果head为空,返回None if not head: return None # temp作为前后比较的指针,初始指向head temp = head # res作为结果链表的指针,初始指向head res = head # 如果还有下一个节点,则前后比较val while temp.next: # 如果前后不相等 if temp.val != temp.next.val: # 让res指向后面那个 res.next = temp.next # res移一个节点 res = res.next temp = temp.next # 循环结束的时候可能最后几个是相同的,扔掉最后几个相同的,只取res指向的那个节点 res.next = None return head
2.合并两个有序数组
题目:
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 输出: [1,2,2,3,5,6]
代码:
class Solution: def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: """ Do not return anything, modify nums1 in-place instead. """ p1=m-1 # 获取nums1的最大索引 p2=n-1 # 获取nums2的最大索引 p=m+n-1 # 获取合并后nums1的最大索引 # 两个列表都还有值 while p1>=0 and p2>=0: # 谁大,谁放后面 if nums1[p1]<nums2[p2]: nums1[p]=nums2[p2] p2-=1 else: nums1[p]=nums1[p1] p1-=1 # p向前移一格 p-=1 # 某个列表没有元素了(假设nums1没有元素了,则剩下的nums2直接拷贝到最前面)(假设nums2没有元素了p2+1=0,所以下面语句不会赋值元素) nums1[:p2+1]=nums2[:p2+1]
总结:
# 这种in-place合并问题,我们可以找到一个正确的方向来写入值,在写入的同时不影响本身还未使用的元素 # 这里我们就选择从nums1的最后(合并后总长度)开始向前按顺序存放值,这样在存放的过程中也不会影响nums1和nums2中途未使用的元素
3.相同的树
题目:
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例:
输入: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3] 输出: true 输入: 1 1 / \ / \ 2 1 1 2 [1,2,1], [1,1,2] 输出: false
代码1:
class Solution: def isSameTree(self, p: TreeNode, q: TreeNode) -> bool: """ :type p: TreeNode :type q: TreeNode :rtype: bool """ # 如果都为None,则相等 if not p and not q: return True # 如果其中有一个为None,另一个不是None,则不相等 if not q or not p: return False # p和q的val不同,不相等 if p.val != q.val: return False # p和q的左右子节点分别相同,才相同 return self.isSameTree(p.right, q.right) and \ self.isSameTree(p.left, q.left)
递归解法。
时间复杂度 : O(N),其中 N 是树的结点数,因为每个结点都访问一次。
空间复杂度 : 最优情况(完全平衡二叉树)时为 O(log(N)),最坏情况下(完全不平衡二叉树)时为O(N),用于维护递归栈。
代码2:
from collections import deque class Solution: def isSameTree(self, p, q): """ :type p: TreeNode :type q: TreeNode :rtype: bool """ # 定义内部函数,用于判断两个节点是否相同 def check(p, q): # if both are None if not p and not q: return True # one of p and q is None if not q or not p: return False if p.val != q.val: return False return True # 使用队列,先将p和q的根节点作为pair元组加入队列(按对加入很重要) deq = deque([(p, q),]) # 当队列中还有pair的时候,就要进行比对,知道队列为空,或者出现不同的对 while deq: # 一对一对拿出来比对 p, q = deq.popleft() # 只要有一对不同,则返回false if not check(p, q): return False # 只要p树还有节点 if p: # 将p的左 q的左做成一对加入队列 deq.append((p.left, q.left)) # 将p的右 q的右做成一对加入队列 deq.append((p.right, q.right)) return True
迭代解法。
时间复杂度 : O(N),其中 N 是树的结点数,因为每个结点都访问一次。
空间复杂度 : 最优情况(完全平衡二叉树)时为 O(log(N)),最坏情况下(完全不平衡二叉树)时为 O(N)。
总结:
# 递归做法比较简洁,但是每轮递归都要开辟栈空间。 # 迭代做法利用了一个队列,由于比较树形结构,所以将其对应节点做为pair是非常好的思想
4.对称二叉树
题目:
给定一个二叉树,检查它是否是镜像对称的。
说明:
如果你可以运用递归和迭代两种方法解决这个问题,会很加分。
示例:
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: 1 / \ 2 2 \ \ 3 3
代码1:
class Solution: def isSymmetric(self, root: TreeNode) -> bool: # 递归,传入判断是否对称的两个节点 def ismirror(left,right): # 如果都为空,表示对称 if not left and not right: return True # 如果只有一个为空,则不对称 if not left or not right: return False # 如果都不为空,但val不同,也不对称 if left.val != right.val: return False # 在当前两个节点对称的情况下,分别在求他们的子节点的是否都对称 return ismirror(left.left, right.right) and ismirror(left.right,right.left) return ismirror(root,root)
递归解法。
代码2:
class Solution: def isSymmetric(self, root: TreeNode) -> bool: from collections import deque if not root: return True deq = deque([(root.left, root.right),]) # st=[root.left,root.right] while deq: l,r=deq.popleft() if not l and not r: continue elif not l or not r: return False elif l.val!=r.val: return False else: deq.append((l.left,r.right)) deq.append((l.right,r.left)) return True
迭代做法,和前面的第3题一样,差不多的思路。
总结:
# 二叉树是否对称和前面第3题(两个二叉树是否相等)思路基本一致 # 二叉树是否对称,可以看成 自己和自己的镜像是否完全相等 # 所以两道题的递归做法和迭代做法都是很相似的
###
保持学习,否则迟早要被淘汰*(^ 。 ^ )***