2020-08-27

2020-08-27  本文已影响0人  想做鹅仔的某福娃
# 234. 回文链表
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        if head is None or head.next is None:
            return True
        # 计算长度
        length = 0
        cur = head
        while cur:
            length += 1
            cur = cur.next

        # 取出后半部分
        length1 = length // 2 if length % 2 == 0 else (length-1) // 2
        new = head
        while length1 > 0:
            new = new.next
            length1 -= 1

        # 反转后半部分
        prev = None
        while new:
            temp = new.next
            new.next = prev
            prev = new
            new = temp

        # 与前半部分逐项对比
        prev_c, head_c = prev, head
        while prev_c:
            if prev_c.val != head_c.val:
                return False
            prev_c = prev_c.next
            head_c = head_c.next
        return True

# 141. 环形链表
class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        slow = fast = head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if slow == fast:
                return True
        return False

# 25. K 个一组翻转链表
class Solution:
    # 翻转一个子链表,并且返回新的头与尾
    def reverse(self, head: ListNode, tail: ListNode):
        prev = tail.next
        p = head
        while prev != tail:
            nex = p.next
            p.next = prev
            prev = p
            p = nex
        return tail, head

    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        hair = ListNode(0)
        hair.next = head
        pre = hair

        while head:
            tail = pre
            # 查看剩余部分长度是否大于等于 k
            for i in range(k):
                tail = tail.next
                if not tail:
                    return hair.next
            nex = tail.next
            head, tail = self.reverse(head, tail)
            # 把子链表重新接回原链表
            pre.next = head
            tail.next = nex
            pre = tail
            head = tail.next

# 206. 反转链表
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        pre = None
        cur = head 
        while cur:
            temp = cur.next 
            cur.next = pre 
            pre = cur 
            cur = temp
        return pre

# 103. 二叉树的锯齿形层次遍历
class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        levels = []
        if root is None:
            return levels
        import collections
        bfs = collections.deque([root])
        flag = 0 #默认从左到右
        while len(bfs) > 0:
            level_size = len(bfs)
            levels.append([])
            if flag == 0:
                for _ in range(level_size):
                    node = bfs.popleft()
                    levels[-1].append(node.val)
                    if node.left is not None:
                        bfs.append(node.left)
                    if node.right is not None:
                        bfs.append(node.right)
                flag = 1
            else:
                for _ in range(level_size):
                    node = bfs.pop()
                    levels[-1].append(node.val)
                    if node.right is not None:
                        bfs.appendleft(node.right)
                    if node.left is not None:
                        bfs.appendleft(node.left)
                flag = 0
        return levels

# 2. 两数相加
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        a = ListNode() # 保留完整的链表
        l3 = a  # 保留完整的链表
        c = 0  # 进位
        while l1 or l2:
            x=l1.val if l1 else 0  # 没有下一节点时取0
            y=l2.val if l2 else 0
            tmp = x+y
            if tmp+c <10:
                l3.next = ListNode(tmp+c)
                c=0  # 不进位,清零
            else:
                l3.next = ListNode(tmp+c-10)
                c=1  # 进位,进1
            # print(tmp)
            # print(l1)
            # print(l2)
            if l1:
                l1 = l1.next  # 进入链表的下一节点
            if l2:
                l2 = l2.next  # 进入链表的下一节点
            l3 = l3.next
        if c==1:
            l3.next = ListNode(1)  # 最后一个进位增加一个末尾节点,元素为1
        return a.next  # a的第一个是0,因此去头节点

# 15. 三数之和
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        
        n=len(nums)
        res=[]
        if(not nums or n<3):
            return []
        nums.sort()
        res=[]
        for i in range(n):
            if(nums[i]>0):
                return res
            if(i>0 and nums[i]==nums[i-1]):
                continue
            L=i+1
            R=n-1
            while(L<R):
                if(nums[i]+nums[L]+nums[R]==0):
                    res.append([nums[i],nums[L],nums[R]])
                    while(L<R and nums[L]==nums[L+1]):
                        L=L+1
                    while(L<R and nums[R]==nums[R-1]):
                        R=R-1
                    L=L+1
                    R=R-1
                elif(nums[i]+nums[L]+nums[R]>0):
                    R=R-1
                else:
                    L=L+1
        return res

# 69. x 的平方根
class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        left, right = 0, x + 1
        # [left, right)
        while left < right:
            mid = left + (right - left) // 2
            if mid ** 2 == x:
                return mid
            if mid ** 2 < x:
                left = mid + 1
            else:
                right = mid
        return left - 1

# 这个问题其实就是求f(x)=num - x ^ 2的零点。

# 已知牛顿法递推公式:Xn+1 = Xn - f(Xn)/f'(Xn).

# 带入f'(x) = -2x.

# 得:
# Xn+1 = Xn +(num - Xn ^ 2)/2Xn
# = (num + Xn ^ 2) / 2Xn
# = (num / Xn + Xn) / 2.

# 用代码表示则为num = (num + x / num) / 2.

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        num = x
        while num * num > x:
            num = (num + x // num) // 2
        return num

# 3. 无重复字符的最长子串
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        # 使用一个辅助变量来暂时存储匹配的子串
        ans = ''
        tep = ''
        for i in s:
            # 遍历,若不重复则记录该字符
            if i not in tep:
                tep += i
            # 如果遇到了已经存在的字符,则找到该字符所在位置,删除该字符,并保留该位置之后的子串,并把当前字符加入到最后,完成更新
            else:
                tep = tep[tep.index(i)+1:]
                tep += i   
            # 如果是当前最长的,就替换掉之前存储的最长子串
            if len(tep) > len(ans): 
                    ans = tep 
        return len(ans)

# 20. 有效的括号
class Solution:
    def isValid(self, s: str) -> bool:
        dic = {')':'(',']':'[','}':'{'}
        stack = []
        for i in s:
            if stack and i in dic:
                if stack[-1] == dic[i]: stack.pop()
                else: return False
            else: stack.append(i)
            
        return not stack

# 143. 重排链表
class Solution:
    def reorderList(self, head: ListNode) -> None:
        """
        Do not return anything, modify head in-place instead.
        """
        # 如果为空,返回None
        if not head:
            return None
        # 找到链表的中间节点
        slow = head
        fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next

        # re_node记录的是后面需要反转链表的头结点,这里奇数节点和偶数节点时的操作是一样的,反转半部分的链表
        re_node = slow.next
        slow.next = None
        dumm = None
        while re_node:
            temp = re_node.next
            re_node.next = dumm
            dumm = re_node
            re_node = temp

        # 开始按照要求合并两个链表
        res = ListNode(0)
        p = res
        while head or dumm:
            if head and dumm:
                # 连接节点
                temp_h = head.next
                temp_d = dumm.next
                p.next = head
                p = p.next
                p.next = dumm
                p =p.next
                head = temp_h
                dumm = temp_d
            else:# 这里是奇数个节点时候,其实也就是会有一个节点需要连接在最后面
                p.next = head
                p = p.next
                head = head.next
        head = res.next

# 162. 寻找峰值
class Solution:
    def findPeakElement(self, nums: List[int]) -> int:
        l=0
        r=len(nums)-1
        while(l<r):
            mid=(l+r)//2
            if(nums[mid]>nums[mid+1]):
                r=mid
            else:
                l=mid+1
        return l

# 215. 数组中的第K个最大元素
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        return sorted(nums)[-k]

class Solution:
    def findKthLargest(self, A: List[int], k: int) -> int:

        def partition(left, right, pivot_idx):
            pivot_value = A[pivot_idx]
            new = left
            A[pivot_idx], A[right] = A[right], A[pivot_idx]
            for i in range(left, right):
                if A[i] > pivot_value:
                    A[i], A[new] = A[new], A[i]
                    new += 1
            A[new], A[right] = A[right], A[new]
            return new
        
        left, right = 0, len(A)-1
        while left <= right:
            pivot_idx = random.randint(left, right)
            new = partition(left, right, pivot_idx)
            if new == k-1:
                return A[new]
            elif new > k-1:
                right = new - 1
            else:
                left = new + 1 

# 124. 二叉树中的最大路径和
class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        self.max_depth = float(-inf)
        def largest_path(root):
            if root is None:
                return float(-inf)
            m_l = largest_path(root.left)
            m_r = largest_path(root.right)
            self.max_depth = max(max(0, m_l) + max(0, m_r) + root.val, m_l, m_r, self.max_depth)
            return max(m_l, m_r, 0) + root.val
        
        largest_path(root)
        return self.max_depth

# 105. 从前序与中序遍历序列构造二叉树 
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        # 实际上inorder 和 postorder一定是同时为空的,因此你无论判断哪个都行
        if not preorder:
            return None
        root = TreeNode(preorder[0])

        i = inorder.index(root.val)
        root.left = self.buildTree(preorder[1:i + 1], inorder[:i])
        root.right = self.buildTree(preorder[i + 1:], inorder[i+1:])

        return root

# 113. 路径总和 II
class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        res = []
        if not root: 
            return []
        
        def dfs(track, root, sum):
            if not root:
                return
            if not root.left and not root.right and root.val == sum:
                track += [root.val]
                res.append(track)
            
            dfs(track + [root.val], root.left, sum - root.val)
            dfs(track + [root.val], root.right, sum - root.val)
        
        dfs([], root, sum)
        return res

# 160. 相交链表


# 114. 二叉树展开为链表

# 146. LRU缓存机制

# 128. 最长连续序列

# 102. 二叉树的层序遍历
上一篇下一篇

猜你喜欢

热点阅读