Golang每日一练(leetDay0047)

news2024/12/29 11:24:46

目录

138. 复制带随机指针的链表 Copy List with Random-pointer  🌟🌟

139. 单词拆分  Word Break  🌟🌟

140. 单词拆分 II  Word Break II  🌟🌟🌟

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


138. 复制带随机指针的链表 Copy List with Random-pointer

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val,random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

示例 1:

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

示例 2:

输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]

示例 3:

输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]

提示:

  • 0 <= n <= 1000
  • -10^4 <= Node.val <= 10^4
  • Node.random 为 null 或指向链表中的节点。

代码:

package main

import "fmt"

const null = -1 << 31

type Node struct {
	Val    int
	Next   *Node
	Random *Node
}

func createNode(val int) *Node {
	return &Node{
		Val:    val,
		Next:   nil,
		Random: nil,
	}
}

func buildRandomList(nodes [][]int) *Node {
	if len(nodes) == 0 {
		return nil
	}

	// 创建普通的链表
	var head, tail *Node
	for _, node := range nodes {
		cur := createNode(node[0])
		if head == nil {
			head = cur
		} else {
			tail.Next = cur
		}
		tail = cur
	}

	// 使用哈希表记录每个节点的位置
	hash := make(map[*Node]int)
	cur := head
	i := 0
	for cur != nil {
		hash[cur] = i
		cur = cur.Next
		i++
	}

	// 遍历链表,修改随机指针
	cur = head
	j := 0
	for cur != nil {
		if nodes[j][1] != null {
			cur.Random = getNode(head, hash, nodes[j][1])
		}
		cur = cur.Next
		j++
	}

	return head
}

func getNode(head *Node, hash map[*Node]int, pos int) *Node {
	cur := head
	for i := 0; i < pos; i++ {
		cur = cur.Next
	}
	return cur
}

func traverseList(head *Node) {
	if head == nil {
		return
	}

	visited := make(map[*Node]bool)
	cur := head
	fmt.Print("[")
	for cur != nil {
		fmt.Print("[")
		fmt.Printf("%d,", cur.Val)
		if cur.Random != nil {
			fmt.Printf("%d", cur.Random.Val)
		} else {
			fmt.Print("null")
		}
		fmt.Print("]")
		visited[cur] = true
		if cur.Next != nil && !visited[cur.Next] {
			fmt.Print(",")
			cur = cur.Next
		} else {
			break
		}
	}
	fmt.Println("]")
}

func copyRandomList(head *Node) *Node {
	if head == nil {
		return nil
	}
	cur := head
	for cur != nil {
		copy := &Node{cur.Val, cur.Next, nil}
		cur.Next = copy
		cur = copy.Next
	}
	cur = head
	for cur != nil {
		if cur.Random != nil {
			cur.Next.Random = cur.Random.Next
		}
		cur = cur.Next.Next
	}
	newHead := head.Next
	cur = head
	for cur != nil {
		copy := cur.Next
		cur.Next = copy.Next
		if copy.Next != nil {
			copy.Next = copy.Next.Next
		}
		cur = cur.Next
	}
	return newHead
}

func copyRandomList2(head *Node) *Node {
	if head == nil {
		return nil
	}

	m := make(map[*Node]*Node)
	cur := head
	for cur != nil {
		m[cur] = &Node{cur.Val, nil, nil}
		cur = cur.Next
	}

	cur = head
	for cur != nil {
		m[cur].Next = m[cur.Next]
		m[cur].Random = m[cur.Random]
		cur = cur.Next
	}

	return m[head]
}

func main() {
	nodes := [][]int{{7, null}, {13, 0}, {11, 4}, {10, 2}, {1, 0}}
	head := buildRandomList(nodes)
	traverseList(head)
	head = copyRandomList(head)
	traverseList(head)

	nodes = [][]int{{1, 1}, {2, 1}}
	head = buildRandomList(nodes)
	traverseList(head)
	head = copyRandomList(head)
	traverseList(head)

	nodes = [][]int{{3, null}, {3, 0}, {3, null}}
	head = buildRandomList(nodes)
	traverseList(head)
	head = copyRandomList(head)
	traverseList(head)
}

输出:

找bug中......


139. 单词拆分  Word Break

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。

示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
     注意,你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

提示:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s 和 wordDict[i] 仅有小写英文字母组成
  • wordDict 中的所有字符串 互不相同

代码1: 暴力枚举

package main

import (
	"fmt"
)

func wordBreak(s string, wordDict []string) bool {
	return helper(s, wordDict)
}

func helper(s string, wordDict []string) bool {
	if s == "" {
		return true
	}
	for i := 1; i <= len(s); i++ {
		if contains(wordDict, s[:i]) && helper(s[i:], wordDict) {
			return true
		}
	}
	return false
}

func contains(wordDict []string, s string) bool {
	for _, word := range wordDict {
		if word == s {
			return true
		}
	}
	return false
}

func main() {
	s := "leetcode"
	wordDict := []string{"leet", "code"}
	fmt.Println(wordBreak(s, wordDict))
	s = "applepenapple"
	wordDict = []string{"apple", "pen"}
	fmt.Println(wordBreak(s, wordDict))
	s = "catsandog"
	wordDict = []string{"cats", "dog", "sand", "and", "cat"}
	fmt.Println(wordBreak(s, wordDict))
}

代码2: 记忆化搜索

package main

import (
	"fmt"
)

func wordBreak(s string, wordDict []string) bool {
	memo := make([]int, len(s))
	for i := range memo {
		memo[i] = -1
	}
	return helper(s, wordDict, memo)
}

func helper(s string, wordDict []string, memo []int) bool {
	if s == "" {
		return true
	}
	if memo[len(s)-1] != -1 {
		return memo[len(s)-1] == 1
	}
	for i := 1; i <= len(s); i++ {
		if contains(wordDict, s[:i]) && helper(s[i:], wordDict, memo) {
			memo[len(s)-1] = 1
			return true
		}
	}
	memo[len(s)-1] = 0
	return false
}

func contains(wordDict []string, s string) bool {
	for _, word := range wordDict {
		if word == s {
			return true
		}
	}
	return false
}

func main() {
	s := "leetcode"
	wordDict := []string{"leet", "code"}
	fmt.Println(wordBreak(s, wordDict))
	s = "applepenapple"
	wordDict = []string{"apple", "pen"}
	fmt.Println(wordBreak(s, wordDict))
	s = "catsandog"
	wordDict = []string{"cats", "dog", "sand", "and", "cat"}
	fmt.Println(wordBreak(s, wordDict))
}

代码3: 动态规划

package main

import (
	"fmt"
)

func wordBreak(s string, wordDict []string) bool {
	n := len(s)
	dp := make([]bool, n+1)
	dp[0] = true
	for i := 1; i <= n; i++ {
		for j := 0; j < i; j++ {
			if dp[j] && contains(wordDict, s[j:i]) {
				dp[i] = true
				break
			}
		}
	}
	return dp[n]
}

func contains(wordDict []string, s string) bool {
	for _, word := range wordDict {
		if word == s {
			return true
		}
	}
	return false
}

func main() {
	s := "leetcode"
	wordDict := []string{"leet", "code"}
	fmt.Println(wordBreak(s, wordDict))
	s = "applepenapple"
	wordDict = []string{"apple", "pen"}
	fmt.Println(wordBreak(s, wordDict))
	s = "catsandog"
	wordDict = []string{"cats", "dog", "sand", "and", "cat"}
	fmt.Println(wordBreak(s, wordDict))
}

输出:

true
true
false


140. 单词拆分 II  Word Break II

给定一个字符串 s 和一个字符串字典 wordDict ,在字符串 s 中增加空格来构建一个句子,使得句子中所有的单词都在词典中。以任意顺序 返回所有这些可能的句子。

注意:词典中的同一个单词可能在分段中被重复使用多次。

示例 1:

输入:s = "catsanddog", wordDict = ["cat","cats","and","sand","dog"]
输出:["cats and dog","cat sand dog"]

示例 2:

输入:s = "pineapplepenapple", wordDict = ["apple","pen","applepen","pine","pineapple"]
输出:["pine apple pen apple","pineapple pen apple","pine applepen apple"]
解释: 注意你可以重复使用字典中的单词。

示例 3:

输入:s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
输出:[]

提示:

  • 1 <= s.length <= 20
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 10
  • s 和 wordDict[i] 仅有小写英文字母组成
  • wordDict 中所有字符串都 不同

代码1: 回溯法

package main

import (
	"fmt"
	"strings"
)

func wordBreak(s string, wordDict []string) []string {
	// 构建字典
	dict := make(map[string]bool)
	for _, word := range wordDict {
		dict[word] = true
	}
	// 回溯函数
	var res []string
	var backtrack func(start int, path []string)
	backtrack = func(start int, path []string) {
		if start == len(s) {
			res = append(res, strings.Join(path, " "))
			return
		}
		for i := start + 1; i <= len(s); i++ {
			if dict[s[start:i]] {
				path = append(path, s[start:i])
				backtrack(i, path)
				path = path[:len(path)-1]
			}
		}
	}
	backtrack(0, []string{})
	return res
}

func ArrayToString(arr []string) string {
	res := "[\""
	for i := 0; i < len(arr); i++ {
		res += arr[i]
		if i != len(arr)-1 {
			res += "\",\""
		}
	}
	res += "\"]"
	if res == "[\"\"]" {
		res = "[]"
	}
	return res
}

func main() {
	s := "catsanddog"
	wordDict := []string{"cat", "cats", "and", "sand", "dog"}
	fmt.Println(ArrayToString(wordBreak(s, wordDict)))
	s = "pineapplepenapple"
	wordDict = []string{"apple", "pen", "applepen", "pine", "pineapple"}
	fmt.Println(ArrayToString(wordBreak(s, wordDict)))
	s = "catsandog"
	wordDict = []string{"cats", "dog", "sand", "and", "cat"}
	fmt.Println(ArrayToString(wordBreak(s, wordDict)))
}

代码2: 动态规划 + 回溯法

package main

import (
	"fmt"
	"strings"
)

func wordBreak(s string, wordDict []string) []string {
	// 构建字典
	dict := make(map[string]bool)
	for _, word := range wordDict {
		dict[word] = true
	}
	// 动态规划
	n := len(s)
	dp := make([]bool, n+1)
	dp[0] = true
	for i := 1; i <= n; i++ {
		for j := 0; j < i; j++ {
			if dp[j] && dict[s[j:i]] {
				dp[i] = true
				break
			}
		}
	}
	if !dp[n] {
		return []string{}
	}
	// 回溯函数
	var res []string
	var backtrack func(start int, path []string)
	backtrack = func(start int, path []string) {
		if start == len(s) {
			res = append(res, strings.Join(path, " "))
			return
		}
		for i := start + 1; i <= len(s); i++ {
			if dict[s[start:i]] {
				path = append(path, s[start:i])
				backtrack(i, path)
				path = path[:len(path)-1]
			}
		}
	}
	backtrack(0, []string{})
	return res
}

func ArrayToString(arr []string) string {
	res := "[\""
	for i := 0; i < len(arr); i++ {
		res += arr[i]
		if i != len(arr)-1 {
			res += "\",\""
		}
	}
	res += "\"]"
	if res == "[\"\"]" {
		res = "[]"
	}
	return res
}

func main() {
	s := "catsanddog"
	wordDict := []string{"cat", "cats", "and", "sand", "dog"}
	fmt.Println(ArrayToString(wordBreak(s, wordDict)))
	s = "pineapplepenapple"
	wordDict = []string{"apple", "pen", "applepen", "pine", "pineapple"}
	fmt.Println(ArrayToString(wordBreak(s, wordDict)))
	s = "catsandog"
	wordDict = []string{"cats", "dog", "sand", "and", "cat"}
	fmt.Println(ArrayToString(wordBreak(s, wordDict)))
}

 代码3: 动态规划 + 记忆化搜索

func wordBreak(s string, wordDict []string) []string {
    // 构建字典
    dict := make(map[string]bool)
    for _, word := range wordDict {
        dict[word] = true
    }
    // 动态规划
    n := len(s)
    dp := make([]bool, n+1)
    dp[0] = true
    for i := 1; i <= n; i++ {
        for j := 0; j < i; j++ {
            if dp[j] && dict[s[j:i]] {
                dp[i] = true
                break
            }
        }
    }
    if !dp[n] {
        return []string{}
    }
    // 记忆化搜索
    memo := make(map[int][][]string)
    var dfs func(start int) [][]string
    dfs = func(start int) [][]string {
        if _, ok := memo[start]; ok {
            return memo[start]
        }
        var res [][]string
        if start == len(s) {
            res = append(res, []string{})
            return res
        }
        for i := start + 1; i <= len(s); i++ {
            if dict[s[start:i]] {
                subRes := dfs(i)
                for _, subPath := range subRes {
                    newPath := append([]string{s[start:i]}, subPath...)
                    res = append(res, newPath)
                }
            }
        }
        memo[start] = res
        return res
    }
    return format(dfs(0))
}
// 格式化结果集
func format(paths [][]string) []string {
    var res []string
    for _, path := range paths {
        res = append(res, strings.Join(path, " "))
    }
    return res
}

输出:

["cat sand dog","cats and dog"]
["pine apple pen apple","pine applepen apple","pineapple pen apple"]
[]


🌟 每日一练刷题专栏 🌟

持续,努力奋斗做强刷题搬运工!

👍 点赞,你的认可是我坚持的动力! 

🌟 收藏,你的青睐是我努力的方向! 

评论,你的意见是我进步的财富!  

 主页:https://hannyang.blog.csdn.net/ 

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

100种思维模型之指数对数思维模型-54

对数、指数&#xff0c;生活中的2种增长曲线&#xff1b;对数增长曲线&#xff0c;即在开始时增长很快&#xff0c;但随着时间的推移&#xff0c;收益会减少并变得更加困难&#xff1b;而指数增长曲线&#xff0c;即开始时增长缓慢&#xff0c;但随着时间的推移&#xff0c;收益…

《计算机网络——自顶向下方法》精炼——2.5-2.6.1

“Be the change you wish to see in the world.” - Mahatma Gandhi 文章目录 DNSDNS概述DNS的组成DNS的服务 DNS运行过程DNS的分布式数据库本地DNS服务器DNS的运行过程递归查询、迭代查询 DNS缓存DNS记录DNS报文首部区域问题区域回答区域权威区域附加区域 插入DNS记录 P2PP2P…

【Shell脚本】shell编程规范与变量

shell编程规范与变量 一、shell脚本概述1.1shell概念1.2Linux有哪些shell1.3shell脚本的作用 二、编写shell脚本的规范2.1编写shell脚本的规范2.2运行shell脚本的两种方法 三、重定向与管道操作3.1交互式与硬件设备3.2重定向操作3.3管道符号 “|” 四、shell变量的作用、类型4.…

WSL2和Windows之间通信实现【以Unity为例】

WSL2可以视为一个独立的虚拟机&#xff0c;具有自己独立的IP地址&#xff0c;通过虚拟路由器与Windows连接&#xff0c;因此WSL2不能直接访问到Windows的主机地址&#xff0c;需要动态获取。 &#xff08;1&#xff09;Windows启用防火墙的WSL2的访问 默认情况下Windows的防火…

陆奇-奇绩创坛-chatGPT新范式,新时代,新机会

奇绩创坛-新范式&#xff0c;新时代&#xff0c;新机会 01-新范式 新范式的新拐点 新范式的历史环境 新范式的社会影响 新范式的缔造者&#xff1a;Sam Altman和OpenAI 新范式的动力引擎 新范式的演化路径 02-新时代 新时代的宏观发展格局 新时代的中国机会 新时代的OpenAI生…

个人复盘和总结 2022——2023

个人心路历程&#xff1a; 从2022年开始接触编程到现在已经断断续续的有一年了。回顾这一年&#xff0c;感觉有进步也有做的不足的地方。好的是从一开始的什么都不会&#xff0c;到现在的至少对计算机有点了解&#xff0c;从C语言到c到Linux系统编程再到Linux网络编程&#xf…

圆桌对话|数字孪生圆桌会议精彩回顾:跨越挑战,迎接机遇

4月20日&#xff0c;以“数实融合&#xff0c;韧性生长”为主题的袋鼠云春季生长大会圆满落幕。本次大会开展了精彩的圆桌会议&#xff0c;在圆桌上&#xff0c;易知微邀请了中国特种设备检测研究院主任&正高级工程师邓贵德、北京中创碳投科技有限公司首席科技官唐进、浙江…

51单片机的中断系统

文章目录 51单片机的中断系统一、中断系统简介程序中断中断可以实现的主要功能中断执行过程 二、51单片中断系统使用中断源中断控制中断允许中断判优中断函数定义 三、中断系统使用案例例一:P3.2 引脚上接了一个按键&#xff0c;P0口连接了8个发光二极管&#xff0c; 要求每次按…

ASIC-WORLD Verilog(9)循环语句

写在前面 在自己准备写一些简单的verilog教程之前&#xff0c;参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好&#xff0c;奈何没有中文&#xff0c;在下只好斗胆翻译过来&#xff08;加了自己的理解&#xff09;分享给大家。 这是网站原文&…

java--ThreadLocal详解

目录 1.ThreadLocal的用途两个使用场景 1.1场景1 1.2两个线程分别用自己的SimpleDateFormat 1.3使用线程池创建1000个打印线程分别用自己的SimpleDateFormat 打印可以看到有很多处两个重复的日期 1.4加锁解决线程安全问题 1.5SimpleDateFormat小结 1.5更好的解决方案是使…

第5章:排序与分页

1.排序数据order by 1.1 排序规则 没有使用排序操作&#xff0c;查询返回的数据是按照添加数据顺序显示 ①&#xff1a;使用order by 子句排序&#xff0c;order by 子句在select语句的结尾 asc(ascend):升序 desc(descend):降序 ②&#xff1a;按照salary从高到低的顺序…

【Linux从入门到精通】Linux常用基础指令(上)

本篇文章会对Linux下的常用进行详细解释&#xff0c;并附加实例。通俗易懂&#xff0c;希望会对你有所帮助。由于内容较多&#xff0c;分为上下篇来讲解。 文章目录 一、什么是Linux的指令呢&#xff1f; 二、Linux下的常用指令 2、1 ls 指令 2、1、1 ls -a 2、1、2 ls -l 2、…

python开发构建基于CNN的人脸识别系统

卷积神经网络在图像处理领域中早就是独树一帜的存在&#xff0c;今天正好有时间就想着基于CNN开发构建一个人脸识别系统&#xff0c;首先看下效果图&#xff1a; 数据集来源于LFW数据集&#xff0c;简单看下本文使用的小批量的数据集如下&#xff1a; 一共有12个人的图像数据&a…

详解git(工作必备)

基本概念 Git 是一个开源的分布式版本控制系统&#xff0c;用以有效、高速的处理从很小到非常大的项目版本管理。 Git 的作用与好处是&#xff1a; 可以帮我们保存文件的所有修改记录&#xff0c;并且使用版本号进行区分&#xff0c;让我们随时可以浏览历史版本、对比不同版本…

Mysql列的完整性约束详解(设置表字段的非空约束(NOT NULL, NK))

设置表字段的非空约束&#xff08;NOT NULL, NK&#xff09; 文章目录 系列文章目录一、设置表字段的非空约束&#xff08;NOT NULL, NK&#xff09; 1.简介2.语句格式总结 一、设置表字段的非空约束&#xff08;NOT NULL, NK&#xff09; 1.简介 当数据库表中的某个字段上的…

perf工具报错,升级ubuntu子系统linux内核

文章目录 1&#xff0c;运行perf工具报错1.1&#xff0c;可能的原因有&#xff1a; 2&#xff0c;我选择升级linux内核&#xff0c;和当前perf工具版本保持一致2.1&#xff0c;下载6.2.12内核源码2.2&#xff0c;安装6.2.12内核 1&#xff0c;运行perf工具报错 1.1&#xff0c;…

今天国际医药行业大型物流系统集成建设案例——广州医药智慧物流中心项目

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 近几年&#xff0c;带量采购常态化、制度化、医保支付方式改革、医保谈判药品“双通道”、线上购药医保结算等一系列政策加速药品流通行业变革步伐&#xff0c;由…

数据驱动的皮肤病变分类深度监测

文章目录 Data-Driven Deep Supervision for Skin Lesion Classification摘要本文方法Layer-Wise Effective Receptive Field (LERF)Object Size Approximation Using Activation MappingDeep Supervision Employment 实验结果 Data-Driven Deep Supervision for Skin Lesion C…

基于html+css的图展示33

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

15天学习MySQL计划-SQL优化/视图(进阶篇)-第八天

SQL优化 1.插入数据&#xff08;insert&#xff09; 1.批量插入 insert into 表名 values(值1,值2),(值1,值2),(值1,值2),(值1,值2) 2.手动提交事务 --查看当前提交的状态 select autocommit; --0代表手动提交 1代表自动提交 set autocommit 0; ​ commit #提交事务 3…