美文网首页
2020-08-27

2020-08-27

作者: 想做鹅仔的某福娃 | 来源:发表于2020-08-27 09:41 被阅读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. 二叉树的层序遍历
    

    相关文章

      网友评论

          本文标题:2020-08-27

          本文链接:https://www.haomeiwen.com/subject/cizqsktx.html