力扣240.搜索二维矩阵II、160.相交链表、206.反转链表

240.搜索二维矩阵II

一、自己写的史山代码(超时)

看到自己写的代码就好笑。。像刚进大学学C语言时会写出来的...感觉白读几年书。。。但还是记录一下,可以忽略这个

python 复制代码
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        m, n = len(matrix), len(matrix[0])
        idx_i, idx_j = 0, 0
        flag = False

        while idx_i < m and idx_j < n:
            if matrix[idx_i][idx_j] == target:
                flag = True
                break
            for i in range(m):
                if matrix[i][idx_j] < target:
                    continue
                if matrix[i][idx_j] == target:
                    idx_i = i
                    flag = True
                    break
                if matrix[i][idx_j] > target:
                    idx_i = i
                    break
            while idx_j >= 0 and matrix[idx_i][idx_j] > target:
                if matrix[idx_i][idx_j] == target:
                    flag = True
                    break
                idx_j -= 1

        return flag

二、二叉搜索树

思路:

二叉搜索树是指根节点的左子树的值都小于根节点,右子树的值都大于根节点,考虑把整个矩阵逆时针旋转45度从上到下就相当于是一个二叉搜索树。后续若target大了就向左遍历找更小值,小了就向右遍历找更大值。

代码:

python 复制代码
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        i, j = 0, len(matrix[0]) - 1
        
        while i < len(matrix) and j >= 0:
            if matrix[i][j] < target: i += 1
            elif matrix[i][j] > target: j -= 1
            else: return True
        
        return False

160.相交链表

自己没想出来。。看的题解

参考:

https://leetcode.cn/problems/intersection-of-two-linked-lists/solutions/12624/intersection-of-two-linked-lists-shuang-zhi-zhen-l

举例理解:

假设链表 headA 和 headB 如下:

headA: A0 -> A1 -> A2 -> C0 -> C1 -> C2
headB: B0 -> B1 -> B2 -> C0 -> C1 -> C2

其中,C0 是交点。则有:

  • 指针 A 的路径:A0 -> A1 -> A2 -> C0 -> C1 -> C2 -> B0 -> B1 -> B2 -> C0
  • 指针 B 的路径:B0 -> B1 -> B2 -> C0 -> C1 -> C2 -> A0 -> A1 -> A2 -> C0

可以看到,两个指针最终在 C0 处相遇。

如果没有交点,假设链表如下:

headA: A0 -> A1 -> A2
headB: B0 -> B1 -> B2

则有:

  • 指针 A 的路径:A0 -> A1 -> A2 -> B0 -> B1 -> B2 -> None
  • 指针 B 的路径:B0 -> B1 -> B2 -> A0 -> A1 -> A2 -> None

两个指针最终同时到达 None,表示没有交点。

注意:

参考链接里面的虽然能通过,但是我理解他给出的代码是建立在两个链表若存在相交点,必然从这一点及之后节点都完全相同,但题目貌似没给出这个条件。所以自己在原代码的基础上加入了一些判断条件,如果后面的节点存在不相同的都返回None。

代码:

python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
        A, B = headA, headB
        while A != B:
            A = A.next if A else headB
            B = B.next if B else headA
        
        # 检查从交点开始的节点是否完全相同
        if A is None:
            return None
        
        # 从交点开始检查
        currentA, currentB = A, A
        while currentA and currentB:
            if currentA != currentB:
                return None  # 从交点开始的节点不完全相同
            currentA = currentA.next
            currentB = currentB.next
        
        return A  # 从交点开始的节点完全相同

206.反转链表

一、双指针法

思路:

1、cur指针指向当前节点,pre指针指向该节点前一节点

2、cur初始化为头节点,pre初始化为None,因为需要反转链表,头节点的下一个翻转过来指向的就是None

3、注意链表修改顺序,先用temp变量暂存cur.next,后续修改cur指向pre,再依次移动cur、pre

代码:

python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 1->2->3->None 反转后相当于
        # None<-3<-2<-1 所以pre设置为None
        cur = head
        pre = None

        while cur:
            # 先存cur.next,因为后面会修改为next指向pre,然后按顺序修改指针指向
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp

        return pre

复杂度分析:

  • 时间复杂度:O(N)
  • 空间复杂度:O(1)

二、递归法

递归三部曲:

1、确定递归函数的参数和返回值:参数------当前节点和前一节点;返回值------反转后的头节点,也就是遍历完的pre(不是cur,因为此时cur已经指向None了)

2、确定终止条件:当cur == None时,返回pre

3、确定单层递归逻辑:cur.next指向pre,同时节点不断往后走

代码:

python 复制代码
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        def reverse(cur, pre):
            # 终止条件
            if cur == None:
                return pre

            temp = cur.next
            cur.next = pre

            return reverse(temp, cur)

        return reverse(head, None)

复杂度分析:

  • 时间复杂度O(N):遍历链表为线性时间大小
  • 空间复杂度O(N):遍历链表的递归深度达到 N ,系统使用 O(N) 大小额外空间

参考:

https://leetcode.cn/problems/reverse-linked-list/solutions/2361282/206-fan-zhuan-lian-biao-shuang-zhi-zhen-r1jel

相关推荐
avi91112 小时前
简单的Gradio实现一个统计界面+日志输出
python·aigc·gradio
jun_bai2 小时前
conda环境配置nnU-Net生物医学图像分割肺动脉静脉血管
开发语言·python
We་ct2 小时前
LeetCode 380. O(1) 时间插入、删除和获取随机元素 题解
前端·算法·leetcode·typescript
老鼠只爱大米2 小时前
LeetCode经典算法面试题 #234:回文链表(双指针法、栈辅助法等多种方法详细解析)
算法·leetcode·链表·递归·双指针·快慢指针·回文链表
独自破碎E2 小时前
【动态规划】兑换零钱(一)
算法·动态规划
Sarvartha2 小时前
顺序表笔记
算法
2301_810730102 小时前
python第一次作业
python
宵时待雨2 小时前
数据结构(初阶)笔记归纳6:双向链表的实现
c语言·开发语言·数据结构·笔记·算法·链表
xixi09242 小时前
selenium——浏览器基础操作(启动/访问/窗口控制)
开发语言·python