力扣练习3.28

138. 随机链表的复制

浅拷贝和深拷贝:
前者新建一个数据结构,不创建元素副本;
后者不仅新建一个数据结构,而且新建一个数据副本。

深拷贝(Deep Copy)和浅拷贝(Shallow
Copy)是在复制数据结构时常见的两个概念,特别是在涉及复杂对象(如链表、树等)时。这两种拷贝方式的主要区别在于它们对原数据结构中对象的处理方式。

浅拷贝(Shallow Copy)

  • 浅拷贝创建一个新的数据结构(如新的链表或数组)但是不创建数据结构中的元素的副本
  • 在浅拷贝中,新数据结构中的元素仍然指向原有数据结构中的相同元素(即对象的引用被复制,而不是对象本身)。
  • 如果原数据结构中的对象被修改,这些修改也会反映在浅拷贝的数据结构中,因为它们共享相同的对象。

深拷贝(Deep Copy)

  • 深拷贝不仅创建一个新的数据结构,还为原数据结构中的每个元素创建副本
  • 在深拷贝中,新数据结构的元素是原元素的副本,这意味着它们是完全独立的。
  • 对原数据结构或深拷贝数据结构中的对象进行的修改不会影响另一个,因为它们不共享对象。

在链表的上下文中

假设有一个链表,其中每个节点都有一个random指针,可以指向链表中的任何节点或null

  • 深拷贝这个链表意味着创建一个新链表,其中包含原链表每个节点的副本,且每个副本节点的nextrandom指针都指向新链表中的对应节点,而不是原链表中的节点。
  • 浅拷贝这个链表则意味着创建一个新链表,但是不为原链表中的节点创建副本。在这种情况下,复制链表中的节点将直接指向原链表中的节点,这通常不是我们想要的。

深拷贝链表的方法

  1. 遍历原链表,为每个原节点创建一个新节点,这个新节点的值与原节点相同,但是nextrandom指针暂时留空。
  2. 建立一个映射关系,将原节点映射到对应的新节点,以便能够设置random指针。
  3. 再次遍历原链表,这次使用映射来设置每个新节点的nextrandom指针。

这种方法确保了每个新节点都与原链表中对应的节点分离,实现了深拷贝。

"""
# Definition for a Node.
class Node:
    def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
        self.val = int(x)
        self.next = next
        self.random = random
"""

class Solution:
    def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
        if not head: return 

        # 建立映射关系 {原节点:新节点}
        old_new = dict()
        cur = head # 当前节点
        while cur:
            old_new[cur] = Node(cur.val, None, None) # 指针部分留空,不然就指向原始链表了
            cur = cur.next # 往后遍历
        
        # 设置新节点的指针,也是从原始的头节点开始
        cur = head
        while cur:
            # 如果有后序节点,就将其从Null更新为原始链表中的后续节点
            if cur.next:
                old_new[cur].next = old_new[cur.next]
            if cur.random:
                old_new[cur].random = old_new[cur.random]
            cur = cur.next

        return old_new[head]
        

297. 二叉树的序列化与反序列化

解题思路:
序列化是将二叉树编码成一个字符串
反序列化是将这个字符串解码成一个二叉树。
针对序列化:考虑使用层序遍历的方法,将二叉树的节点自上而下、从左往右地放在字符串里。不能忘了空节点,使用特殊符号占位,并分隔;
针对反序列化:针对字符串根据分隔符转换为list,初始化根节点,另其值等于list的首个元素。然后按照层序遍历的方式,将每层的节点指向列表的对应元素值,使用一个全局的索引变量解决。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Codec:

    def serialize(self, root):
        """Encodes a tree to a single string.
        
        :type root: TreeNode
        :rtype: str
        """
        # 序列化
        # 层序遍历,将其结果都存储到一个字符串,用;分隔
        if not root: return '#;'
        res = ''
        queue = [root]
        while queue: # 因为最后只要一个字符串,所以就省略了
            node = queue.pop(0)
            # 如果节点存在,结果字符串加上节点的值
            if node: 
                res += f'{node.val};'
                queue.append(node.left) # 加左子节点
                queue.append(node.right) # 右子节点
            else: # 如果是空,那就加上空值占位符
                res += '#;'
        return res
        

    def deserialize(self, data):
        """Decodes your encoded data to tree.
        
        :type data: str
        :rtype: TreeNode
        """
        # 反序列化
        # 将字符串拆分为list
        if data == '#;': return None
        nodes = data.split(';')[:-1] # 因为这样分隔最后会出现空格,删除
        root = TreeNode(int(nodes[0])) # 根节点设置
        # 类似层序遍历
        queue = [root] # 层序遍历的起始
        index = 1 # 记录数组索引,0已经被定义了(根节点)
        while queue:
            node = queue.pop(0) # 第一次就是根节点
            # 如果当前节点不为空,也就是 不是#
            if nodes[index] != '#': 
                node.left = TreeNode(int(nodes[index])) # 按照层序遍历,是从左到右的
                queue.append(node.left) # 队列结尾加上下一层的左节点 
            index += 1 # 左边的经过处理后就索引+1,不管是不是空值
            # 对右边执行相同操作
            if nodes[index] != '#':
                node.right = TreeNode(int(nodes[index]))
                queue.append(node.right)
            index += 1
        # 返回根节点
        return root



# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))

209. 长度最小的子数组

解题思路:双指针,滑动窗口。
从开始,逐步扩展窗口,检测是否满足求和条件;一旦满足,就缩减窗口,满足的时候也要比较最小的窗口长度。
可以使用for循环或者两层while。要注意的是for循环默认在执行完循环主体后进入下一个遍历。while循环需要手动在最后加,如果在前面加那么最小长度就不能+1,因为此时右指针正好跑过满足条件的窗口了。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        # 双指针,滑动窗口
        # 先不断扩展窗口,等满足条件就逐步缩小窗口
        # 左指针
        left = 0
        temp = 0 # 窗口内的和
        min_len = float('inf') # 最小长度
        # 循环
        for right in range(len(nums)):
            # 窗口内总和
            temp += nums[right]
            # 满足条件,开始缩减窗口
            while temp >= target:
                min_len = min(min_len, right-left+1)
                temp -= nums[left]
                left += 1
        # 检测最终是否有最短的存在
        if min_len != float('inf'):
            return min_len
        else:
            return 0

使用两层while循环

def minSubArrayLen(target, nums):
    n = len(nums)
    min_len = float('inf')  # 初始化为无穷大,用以比较找到最小长度
    sum = 0  # 窗口内元素的总和
    left, right = 0, 0  # 双指针,都初始化为0
    
    while right < n:
        # 扩大窗口
        sum += nums[right]
        right += 1
        
        # 当窗口内的总和大于等于target时,尝试缩小窗口以找到最小长度
        while sum >= target:
            min_len = min(min_len, right - left)
            sum -= nums[left]
            left += 1
    
    return min_len if min_len != float('inf') else 0

139. 单词拆分

这个问题可以通过动态规划来解决。动态规划是一种解决复杂问题的方法,它将问题分解成更小的子问题,通过解决子问题来解决整个问题。

动态规划思路

定义状态:定义一个布尔类型的动态规划数组dp,其中dp[i]表示字符串s的前i个字符(s[0..i-1])能否被字典wordDict中的一个或多个单词拼接得出。

状态转移:为了确定dp[i]的值,我们需要遍历[0, i)的所有可能的分割点j,检查两个条件:

  1. 字符串s[j..i-1](即从ji-1的子串)是否存在于字典wordDict中。
  2. dp[j]是否为true,表示s[0..j-1]可以被拼接得出。

如果上述两个条件中的任何一个为true,则dp[i]也为true

初始化dp[0] = true,表示空字符串总是可以被表示。

目标:检查dp[s.length()]的值,如果为true,表示整个字符串s可以用字典中的一个或多个单词拼接得出。

示例代码

def wordBreak(s, wordDict):
    word_set = set(wordDict)  # 将字典转换为集合,便于查找
    dp = [False] * (len(s) + 1)
    dp[0] = True  # 空字符串总是可以被表示

    for i in range(1, len(s) + 1):
        for j in range(i):
            if dp[j] and s[j:i] in word_set:
                dp[i] = True
                break  # 一旦找到一个有效的分割点,就可以停止查找

    return dp[-1]

解释

  • 循环遍历字符串s的所有子串。
  • 对于每个子串s[j:i],如果dp[j]true且子串在wordDict中,说明找到了一个有效的分割点j,将dp[i]设置为true
  • 最终,dp[-1](或dp[len(s)])的值会告诉我们是否可以用字典中的单词拼接出整个字符串s

这种方法通过动态规划避免了重复计算和不必要的搜索,有效地解决了问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/497996.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【React】onClick点击事件传参的4种方式

记录React onClick 点击事件传参的 4 种方式 方式一&#xff1a;使用内联箭头函数 import React, { MouseEvent } from "react";function App() {const handleClick (event: MouseEvent<HTMLButtonElement>, name: string) > {console.log(event)console.…

linux 环境安装配置

安装java17 1.下载安装包 wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz 2.解压到自定义目录/usr/local/java mkdir /usr/local/java tar zxvf jdk-17_linux-x64_bin.tar.gz -C /usr/local/java 3.配置环境变量 echo export PATH$PATH:/…

Docker 夺命连环 15 问

目录 什么是Docker&#xff1f; Docker的应用场景有哪些&#xff1f; Docker的优点有哪些&#xff1f; Docker与虚拟机的区别是什么&#xff1f; Docker的三大核心是什么&#xff1f; 如何快速安装Docker&#xff1f; 如何修改Docker的存储位置&#xff1f; Docker镜像常…

2024年购买阿里云服务器多少钱?100元到500元年预算

2024年阿里云服务器优惠价格表&#xff0c;一张表整理阿里云服务器最新报价&#xff0c;阿里云服务器网aliyunfuwuqi.com整理云服务器ECS和轻量应用服务器详细CPU内存、公网带宽和系统盘详细配置报价单&#xff0c;大家也可以直接移步到阿里云CLUB中心查看 aliyun.club 当前最新…

分享react+three.js展示温湿度采集终端

前言 气象站将采集到的相关气象数据通过GPRS/3G/4G无线网络发送到气象站监测中心&#xff0c;摆脱了地理空间的限制。 前端&#xff1a;气象站主机将采集好的气象数据存储到本地&#xff0c;通过RS485等线路与GPRS/3G/4G无线设备相连。 通信&#xff1a;GPRS/3G/4G无线设备通…

Vue 03 组件通信

Vue学习 Vue 0301 浏览器本地存储localStorageSessionStorage案例 todolist的完善 02 组件自定义事件Custom Events基本使用解绑自定义事件注意事项①② 总结案例 todolist的完善 03 全局事件总线GlobalEventBus案例 todolist的完善 04 消息的订阅与发布案例 todolist的完善 05…

利用R语言和curl库实现网页爬虫的技术要点解析

R语言简介 R语言是一种自由、跨平台的编程语言和软件环境&#xff0c;专门用于统计计算和数据可视化。它具有丰富的数据处理、统计分析和图形展示功能&#xff0c;被广泛应用于数据科学、机器学习、统计建模等领域。 R语言技术优势 丰富的数据处理功能&#xff1a; R语言拥有…

unity双层滑动实现

实现功能&#xff1a; 当滑动列表中内容处于顶端的时候&#xff0c;向上滑动优先滑动整个滑动列表&#xff0c;当滑动列表移动到设置位置&#xff0c;即设定的最高处时&#xff0c;继续移动列表内内容。向下移动亦然&#xff0c;当内容处于滑动列表顶端时&#xff0c;移动整个滑…

低功耗、低成本 NAS/公共文件夹 的可能性

使用现状&#xff1a;多台工作电脑&#xff0c;家里人手一台&#xff0c;还在两个住处 有好几台工作电脑&#xff0c;不同电脑不同OS有不同的用途&#xff0c;最大的问题就是各个电脑上文件的同步问题&#xff0c;这里当然就需要局域网里的公共文件夹&#xff0c;在NAS的问题上…

R语言使用dietaryindex包计算NHANES数据多种营养指数(2)

健康饮食指数 (HEI) 是评估一组食物是否符合美国人膳食指南 (DGA) 的指标。Dietindex包提供用户友好的简化方法&#xff0c;将饮食摄入数据标准化为基于指数的饮食模式&#xff0c;从而能够评估流行病学和临床研究中对这些模式的遵守情况&#xff0c;从而促进精准营养。 该软件…

Unity3d使用Jenkins自动化打包(Windows)(一)

文章目录 前言一、安装JDK二、安装Jenkins三、Jenkins插件安装和使用基础操作 实战一基础操作 实战二 四、离线安装总结 前言 本篇旨在介绍基础的安装和操作流程&#xff0c;只需完成一次即可。后面的篇章将深入探讨如何利用Jenkins为Unity项目进行打包。 一、安装JDK 1、进入…

【嵌入式机器学习开发实战】(十二)—— 政安晨:通过ARM-Linux掌握基本技能【C语言程序的安装运行】

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 嵌入式机器学习开发实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 在ARM-Linux系统中&#xff0c;C语言程序的安装和运行可…

快速上手Spring Cloud 六:容器化与微服务化

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

啥也不会的大学生看过来,这8步就能系统入门stm32单片机???

大家好&#xff0c;今天给大家介绍啥也不会的大学生看过来&#xff0c;这8步就能系统入门stm32单片机&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 对于没有任何基础的大学生来…

数据库原理与应用(SQL Server)笔记 关系数据库

目录 一、关系数据库的基本概念&#xff08;一&#xff09;关系数据库的定义&#xff08;二&#xff09;基本表、视图&#xff08;三&#xff09;元组、属性、域&#xff08;四&#xff09;候选码、主码、外码 二、关系模型三、关系的完整性&#xff08;一&#xff09;实体完整…

快速上手Spring Cloud五:Spring Cloud与持续集成/持续部署(CI/CD)

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

神策数据参与制定首份 SDK 网络安全国家标准

国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2023 年第 13 号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的 3 项国家标准正式发布。其中&#xff0c;首份 SDK 国家标准《信息安全技术 移动互联网应用程序&#xff0…

根据实例逐行分析NIO到底在做什么

Selector&#xff08;选择器&#xff09;是 Channel 的多路复用器&#xff0c;它可以同时监控多个 Channel 的 IO 状况&#xff0c;允许单个线程来操作多个 Channel。Channel在从Buffer中获取数据。 选择器、通道、缓冲池是NIO的核心组件。 一、新建选择器 此时选择器内只包含…

HackTheBox-Machines--Legacy

文章目录 1 端口扫描2 测试思路3 445端口漏洞测试4 flag Legacy 测试过程 1 端口扫描 nmap -sC -sV 10.129.227.1812 测试思路 目标开启了135、139、445端口&#xff0c;445 SMB服务存在很多可利用漏洞&#xff0c;所以测试点先从445端口开始。而且在Nmap扫描结果中&#xff0c…

操作系统练习-操作系统的发展与分类

批量处理系统 ----------------------------------------------------------------------------------------------------------------------------- 1. 下列关于批处理系统的叙述中&#xff0c;正确的是( )。 I.批处理系统允许多个用户与计算…
最新文章