力扣剑指Offer-简单II

# ========================25 合并两个排序的链表===================================
#答案的版本
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        cur = dum = ListNode(0)
        while l1 and l2:
            if l1.val < l2.val:
                cur.next, l1 = l1, l1.next
            else:
                cur.next, l2 = l2, l2.next
            cur = cur.next
        cur.next = l1 if l1 else l2
        return dum.next

#我写的版本
class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if l1 == None:
            return l2
        if l2 == None:
            return l1
        ill = ListNode(0)  #(1)
        cur = ill    #(2)
##(1)(2)处不能写成 ill = ListNode(0)  cur = ListNode(0)  否则会报错。
        while l1 and l2:
            if l1.val <= l2.val:
                cur.next = l1
                l1 = l1.next
                cur = cur.next
            if l2.val < l1.val:
                cur.next = l2
                l2 = l2.next
                cur = cur.next
        if l1 == None:
            cur.next = l2
        if l2 == None:
            cur.next = l1

        return ill.next
# =============================================================================
# ===========09 两个栈实现队列===================================================
#这是答案
class CQueue:
    def __init__(self):
        self.A, self.B = [], []

    def appendTail(self, value: int) -> None:
        self.A.append(value)

    def deleteHead(self) -> int:
        if self.B: 
            return self.B.pop()
        if not self.A: 
            return -1
        while self.A:
            self.B.append(self.A.pop())
        return self.B.pop()
        
#这是我的版本,我也不知道为什么出错了....  
class CQueue:

    def __init__(self):
        self.s1 = []
        self.B = []
    def appendTail(self, value: int) -> None:
        self.s1.append(value)
    def deleteHead(self) -> int:
        if self.s1 == None:
            return -1
        if self.B:
            return self.B.pop()
        while self.s1 :
            a = self.s1.pop()
            self.B.append(a)
        return self.B.pop()
#这是牛客网上的版本,同样的代码在力扣上就运行出错。我也不知道为什么

class Solution:
    def __init__(self):
        self.stack1,self.stack2=[],[]
        
    def push(self, node):
        # write code here
        self.stack1.append(node)
    def pop(self):
        # return xx
        if self.stack2:   #如果非空,则执行下面的操作
            return self.stack2.pop()
        elif not self.stack1:  #如果是空的,则返回None
            return None
        else:
            while self.stack1: #如果非空,则执行下面的操作
                self.stack2.append(self.stack1.pop())
            return self.stack2.pop()
# =============================================================================
# =================57 II和为s的连续正整数序列=====================================
#滑动窗口一般是左闭右开区间。且开始时i = 1;j = 1;sum = 0
def findContinuousSequence(self, target: int) -> List[List[int]]:
    i = 1 # 滑动窗口的左边界
    j = 1 # 滑动窗口的右边界
    sum = 0 # 滑动窗口中数字的和
    res = []

    while i <= target // 2:  #注意一下,这里是<=而不是<
        if sum < target:
            # 右边界向右移动
            sum += j
            j += 1
        elif sum > target:
            # 左边界向右移动
            sum -= i
            i += 1
        else:
            # 记录结果
            arr = list(range(i, j))  #注意一下,先记录数据然后sum再减少
            res.append(arr)
            # 左边界向右移动
            sum -= i
            i += 1

    return res
# =============================================================================
# ========68-II二叉树的最近公共祖先****(不太明白算法实现)=============================
'''
最近公共祖先的定义: 设节点 rootroot 为节点 p, q的某公共祖先,
若其左子节点root.leftroot.left 和右子节点 root.rightroot.right 都不是 p,q 的公共祖先,
则称 rootroot 是 “最近的公共祖先”。
'''
class Solution:
    def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
        if not root or root == p or root == q: #先考虑根节点的情况
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if not left: 
            return right
        if not right: 
            return left
        return root
# =============================================================================
# ==============68-I二叉搜索树的最近公共祖先=======================================
#可以用68-II的程序,也可以用下面的这个
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        while root:
            if root.val < p.val and root.val < q.val: # p,q 都在 root 的右子树中
                root = root.right # 遍历至右子节点
            elif root.val > p.val and root.val > q.val: # p,q 都在 root 的左子树中
                root = root.left # 遍历至左子节点
            else: break
        return root
# =============================================================================
# ===============39 数组中出现次数超过一半的数字====================================
#这是我写的代码
class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        res = {}
        temp = []
        lenth = len(nums)
        for i in nums:
            if i in temp:
                res[i] += 1
            else:
                res[i] = 1
            temp.append(i)
        for i in temp:
            if res[i] > lenth // 2:
                return i
# =============================================================================
# ===================32-II从上到下打印二叉树II====================================
#从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
''' 
按层打印: 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。BFS 通常借助 队列 的先入先出特性来实现。
'''
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: 
            return []
        res, queue = [], collections.deque()  #deque(双端队列)是一个数据结构。collections是一个模块
        #res 是打印结果的列表  queue是储存每一层节点的队列
        queue.append(root) #首先把根加进去
        ##初始化,queue是一个包含根节点的双端队列
        while queue:
            tmp = []  #创建一个临时的列表,保存当前层的节点
            for _ in range(len(queue)):
                # _表示占位符  不会打印出指标值,仅仅表示要循环range次
                node = queue.popleft()
                tmp.append(node.val)
                if node.left: 
                    queue.append(node.left)
                if node.right: 
                    queue.append(node.right)
            res.append(tmp)
        return res

# https://www.bilibili.com/video/BV1vQ4y1M7wv/  这道题的视频讲解
# =============================================================================
# ============03 数组中重复的数字=================================================
class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        res = {}
        for i in nums:
            if i in res:
                res[i] += 1
            else:
                res[i] = 1
        fanhui = []
        for i in nums:
            if res[i] >= 2:
                return i
# =============================================================================
# ===============50 第一个只出现一次的字符=========================================
class Solution:
    def firstUniqChar(self, s: str) -> str:
        sNew = list(s)
        if not sNew:
            return ' '
        res = {}
        for i in sNew:
            if i in res:
                res[i] += 1
            else:
                res[i] = 1
        for i in sNew:
            if res[i] == 1:
                return ''.join(i)
        temp = []
        for i in sNew:
            if res[i] == 1:
                temp.append(i)
        if not temp:
            return ' '
# =============================================================================
# ===================65 不用加减乘除做加法========================================
class Solution:
    def add(self, a: int, b: int) -> int:
        c = []
        c.append(a)
        c.append(b)
        d = sum(c)
        return d
# =============================================================================
# ==============57 和为s的两个数字===============================================
#答案
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        i, j = 0, len(nums) - 1
        while i < j:
            s = nums[i] + nums[j]
            if s > target:
                j -= 1
            elif s < target: 
                i += 1
            else: 
                return nums[i], nums[j]
        return []
#我写的版本,但是会输出null,也不知道为什么
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        res = []
        n = len(nums)
        temp1 = []
        temp2 = []
        for k in range(n - 1):
            for i in range(1,n):
                sumN = nums[k] + nums[i]
                res.append(sumN)
                temp1 = k,i
                temp1 = list(temp1)
                temp2.append(temp1)  
        for i in range(n * (n - 1)// 2):
            if res[i] == target:
                a = temp2[i][0]
                b = temp2[i][1]
                return nums[a],nums[b]
# =============================================================================
    

# ==============62 圆圈中剩下的最后一个字==========================================
'''
模拟整个删除过程最直观,即构建一个长度为 nn 的链表,各节点值为对应的顺序索引;每轮删除第 mm 个
节点,直至链表长度为 1 时结束,返回最后剩余节点的值即可。
'''
#这是一道数学问题,我还没有看明白
class Solution:
    def lastRemaining(self, n: int, m: int) -> int:
          x = 0
          for i in range(2, n + 1):
              x = (x + m) % i
          return x
#=============================================================================

#==============21 调整数组顺序使得奇数位于偶数前面==================================
class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        i, j = 0, len(nums) - 1
        while i < j:
            while i < j and nums[i] % 1 == 1: #奇数
                i += 1
            while i < j and nums[j] % 1 == 0: #偶数   
                j -= 1
            nums[i], nums[j] = nums[j], nums[i]
        return nums  #这一行是和while并列的
# =============================================================================
# ==========52 两个链表的第一个公共节点============================================
#牛客网的版本.但是在力扣上运行错误,因为力扣上要求输出一个ListNode
class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        p1 = headA
        p2 = headB
        if p1 == None or p2 == None:
            return None
        stack1 = []
        stack2 = []
        while p1:
            stack1.append(p1)
            p1 = p1.next
        while p2:
            stack2.append(p2)
            p2 = p2.next
        re = None
        while stack1 and stack2:
            s1jqnum = stack1.pop()
            s2jqnum = stack2.pop()
            if s1jqnum == s2jqnum:
                return s1jqnum
#力扣上的版本
'''
a+(b-c)=b+(a-c)
超级聪明
'''
class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        node1, node2 = headA, headB      
        while node1 != node2:
            if node1:
                node1 = node1.next
            else:
                node1 = headB
            if node2:
                node2 = node2.next
            else:
                node2 = headA
        return node1
# =============================================================================
# ============46 连续子数组的最大和===============================================
#答案
#这个方法太奇妙了
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        for i in range(1, len(nums)):
            nums[i] += max(nums[i - 1], 0)
        return max(nums)
#我写的暴力计算,但是超出了时间限制
class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        
        sumList = []
        for i in range(len(nums)):
            sumN = 0   
            for j in range(i,len(nums)):
                sumN += nums[j]
                sumList.append(sumN)
        re = max(sumList)
        return re
# =============================================================================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十子木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值