Golang每日一练(leetDay0033) 二叉树专题(2)

news2025/6/16 16:03:34

目录

97. 交错字符串 Interleaving String  🌟🌟 

98. 验证二叉搜索树 Validate Binary Search Tree  🌟🌟

99. 恢复二叉搜索树 Recover Binary Search Tree  🌟🌟

🌟 每日一练刷题专栏 🌟

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏


二叉树专题(2)第97题除外

97. 交错字符串 Interleaving String

给定三个字符串 s1s2s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。

两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:

  • s = s1 + s2 + ... + sn
  • t = t1 + t2 + ... + tm
  • |n - m| <= 1
  • 交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...

注意:a + b 意味着字符串 a 和 b 连接。

示例 1:

输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出:true

示例 2:

输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出:false

示例 3:

输入:s1 = "", s2 = "", s3 = ""
输出:true

提示:

  • 0 <= s1.length, s2.length <= 100
  • 0 <= s3.length <= 200
  • s1s2、和 s3 都由小写英文字母组成

进阶:您能否仅使用 O(s2.length) 额外的内存空间来解决它?

代码1:动态规划

package main

import (
	"fmt"
)

func isInterleave(s1 string, s2 string, s3 string) bool {
	if len(s1)+len(s2) != len(s3) {
		return false
	}
	dp := make([][]bool, len(s1)+1)
	for i := range dp {
		dp[i] = make([]bool, len(s2)+1)
	}
	dp[0][0] = true
	for i := 1; i <= len(s1); i++ {
		dp[i][0] = dp[i-1][0] && s1[i-1] == s3[i-1]
	}
	for j := 1; j <= len(s2); j++ {
		dp[0][j] = dp[0][j-1] && s2[j-1] == s3[j-1]
	}
	for i := 1; i <= len(s1); i++ {
		for j := 1; j <= len(s2); j++ {
			if s1[i-1] == s3[i+j-1] {
				dp[i][j] = dp[i][j] || dp[i-1][j]
			}
			if s2[j-1] == s3[i+j-1] {
				dp[i][j] = dp[i][j] || dp[i][j-1]
			}
		}
	}
	return dp[len(s1)][len(s2)]
}

func main() {
	s1 := "aabcc"
	s2 := "dbbca"
	s3 := "aadbbcbcac"
	fmt.Println(isInterleave(s1, s2, s3))
	s1 = "aabcc"
	s2 = "dbbca"
	s3 = "aadbbbaccc"
	fmt.Println(isInterleave(s1, s2, s3))
	s1 = ""
	s2 = ""
	s3 = ""
	fmt.Println(isInterleave(s1, s2, s3))
}

输出:

true
false
true

代码2:广度优先搜索

package main

import (
	"fmt"
)

func isInterleave(s1 string, s2 string, s3 string) bool {
	if len(s1)+len(s2) != len(s3) {
		return false
	}
	queue := [][]int{{0, 0}}
	visited := make([][]bool, len(s1)+1)
	for i := range visited {
		visited[i] = make([]bool, len(s2)+1)
	}
	for len(queue) > 0 {
		i, j := queue[0][0], queue[0][1]
		queue = queue[1:]
		if visited[i][j] {
			continue
		}
		visited[i][j] = true
		if i == len(s1) && j == len(s2) {
			return true
		}
		if i < len(s1) && s1[i] == s3[i+j] {
			queue = append(queue, []int{i + 1, j})
		}
		if j < len(s2) && s2[j] == s3[i+j] {
			queue = append(queue, []int{i, j + 1})
		}
	}
	return false
}

func main() {
	s1 := "aabcc"
	s2 := "dbbca"
	s3 := "aadbbcbcac"
	fmt.Println(isInterleave(s1, s2, s3))
	s1 = "aabcc"
	s2 = "dbbca"
	s3 = "aadbbbaccc"
	fmt.Println(isInterleave(s1, s2, s3))
	s1 = ""
	s2 = ""
	s3 = ""
	fmt.Println(isInterleave(s1, s2, s3))
}

98. 验证二叉搜索树 Validate Binary Search Tree

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:root = [2,1,3]
输出:true

示例 2:

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 10^4] 内
  • -2^31 <= Node.val <= 2^31 - 1

代码1:

package main

import (
	"fmt"
)

const null = -1 << 31

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

func isValidBST(root *TreeNode) bool {
	var pre *TreeNode
	return validate(root, &pre)
}

func validate(node *TreeNode, pre **TreeNode) bool {
	if node == nil {
		return true
	}
	if !validate(node.Left, pre) {
		return false
	}
	if *pre != nil && node.Val <= (*pre).Val {
		return false
	}
	*pre = node
	return validate(node.Right, pre)
}

func buildTree(nums []int) *TreeNode {
	if len(nums) == 0 {
		return nil
	}
	root := &TreeNode{Val: nums[0]}
	Queue := []*TreeNode{root}
	idx := 1
	for idx < len(nums) {
		node := Queue[0]
		Queue = Queue[1:]
		if nums[idx] != null {
			node.Left = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Left)
		}
		idx++
		if idx < len(nums) && nums[idx] != null {
			node.Right = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Right)
		}
		idx++
	}
	return root
}

func (root *TreeNode) LevelOrder() []int {
	var res []int
	if root == nil {
		return res
	}
	Queue := []*TreeNode{root}
	for len(Queue) > 0 {
		cur := Queue[0]
		Queue = Queue[1:]
		res = append(res, cur.Val)
		if cur.Left != nil {
			Queue = append(Queue, cur.Left)
		}
		if cur.Right != nil {
			Queue = append(Queue, cur.Right)
		}
	}
	return res
}

func main() {
	nums := []int{2, 1, 3}
	root := buildTree(nums)
	fmt.Println(isValidBST(root))
	nums = []int{5, 1, 4, null, null, 3, 6}
	root = buildTree(nums)
	fmt.Println(isValidBST(root))
	nums = []int{3, 1, 5, null, null, 4, 6}
	root = buildTree(nums)
	fmt.Println(isValidBST(root))
}

输出:

true
false
true

代码2: 递归法

package main

import (
	"fmt"
)

const null = -1 << 31

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

func isValidBST(root *TreeNode) bool {
	return validate(root, nil, nil)
}

func validate(node *TreeNode, min *int, max *int) bool {
	if node == nil {
		return true
	}
	if (min != nil && node.Val <= *min) || (max != nil && node.Val >= *max) {
		return false
	}
	return validate(node.Left, min, &node.Val) && validate(node.Right, &node.Val, max)
}

func buildTree(nums []int) *TreeNode {
	if len(nums) == 0 {
		return nil
	}
	root := &TreeNode{Val: nums[0]}
	Queue := []*TreeNode{root}
	idx := 1
	for idx < len(nums) {
		node := Queue[0]
		Queue = Queue[1:]
		if nums[idx] != null {
			node.Left = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Left)
		}
		idx++
		if idx < len(nums) && nums[idx] != null {
			node.Right = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Right)
		}
		idx++
	}
	return root
}

func main() {
	nums := []int{2, 1, 3}
	root := buildTree(nums)
	fmt.Println(isValidBST(root))
	nums = []int{5, 1, 4, null, null, 3, 6}
	root = buildTree(nums)
	fmt.Println(isValidBST(root))
	nums = []int{3, 1, 5, null, null, 4, 6}
	root = buildTree(nums)
	fmt.Println(isValidBST(root))
}

 代码3: 中序遍历+判断

package main

import (
	"fmt"
)

const null = -1 << 31

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

func isValidBST(root *TreeNode) bool {
	var pre *TreeNode
	stack := []*TreeNode{}
	for root != nil || len(stack) > 0 {
		for root != nil {
			stack = append(stack, root)
			root = root.Left
		}
		node := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		if pre != nil && node.Val <= pre.Val {
			return false
		}
		pre = node
		root = node.Right
	}
	return true
}

func buildTree(nums []int) *TreeNode {
	if len(nums) == 0 {
		return nil
	}
	root := &TreeNode{Val: nums[0]}
	Queue := []*TreeNode{root}
	idx := 1
	for idx < len(nums) {
		node := Queue[0]
		Queue = Queue[1:]
		if nums[idx] != null {
			node.Left = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Left)
		}
		idx++
		if idx < len(nums) && nums[idx] != null {
			node.Right = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Right)
		}
		idx++
	}
	return root
}

func main() {
	nums := []int{2, 1, 3}
	root := buildTree(nums)
	fmt.Println(isValidBST(root))
	nums = []int{5, 1, 4, null, null, 3, 6}
	root = buildTree(nums)
	fmt.Println(isValidBST(root))
	nums = []int{3, 1, 5, null, null, 4, 6}
	root = buildTree(nums)
	fmt.Println(isValidBST(root))
}

99. 恢复二叉搜索树 Recover Binary Search Tree

给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 

示例 1:

输入:root = [1,3,null,null,2]
输出:[3,1,null,null,2]
解释:3 不能是 1 的左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。

示例 2:

输入:root = [3,1,4,null,null,2]
输出:[2,1,4,null,null,3]
解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。

提示:

  • 树上节点的数目在范围 [2, 1000] 内
  • -2^31 <= Node.val <= 2^31 - 1

进阶:使用 O(n) 空间复杂度的解法很容易实现。你能想出一个只使用 O(1) 空间的解决方案吗?

代码1:中序遍历+交换节点值

对于二叉搜索树,中序遍历得到的序列是递增的。因此,如果有两个节点的值被错误地交换了,那么在中序遍历序列中一定存在两个相邻的逆序对。具体做法是,在中序遍历的过程中,用一个变量pre记录上一个遍历到的节点,每次遍历到一个节点时,判断其值是否小于pre的值,如果小于,则说明存在逆序对,记录下这两个节点,并继续遍历。最后,交换这两个节点的值即可。

package main

import (
	"fmt"
	"strconv"
)

const null = -1 << 31

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

func recoverTree(root *TreeNode) {
	var pre, first, second *TreeNode
	var stack []*TreeNode
	for root != nil || len(stack) > 0 {
		for root != nil {
			stack = append(stack, root)
			root = root.Left
		}
		node := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		if pre != nil && node.Val < pre.Val {
			if first == nil {
				first = pre
			}
			second = node
		}
		pre = node
		root = node.Right
	}
	first.Val, second.Val = second.Val, first.Val
}

func buildTree(nums []int) *TreeNode {
	if len(nums) == 0 {
		return nil
	}
	root := &TreeNode{Val: nums[0]}
	Queue := []*TreeNode{root}
	idx := 1
	for idx < len(nums) {
		node := Queue[0]
		Queue = Queue[1:]
		if nums[idx] != null {
			node.Left = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Left)
		}
		idx++
		if idx < len(nums) && nums[idx] != null {
			node.Right = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Right)
		}
		idx++
	}
	return root
}

func levelOrder(root *TreeNode) string {
	if root == nil {
		return "[]"
	}
	arr := []int{}
	que := []*TreeNode{root}
	for len(que) > 0 {
		levelSize := len(que)
		for i := 0; i < levelSize; i++ {
			node := que[0]
			que = que[1:]
			if node == nil {
				arr = append(arr, null)
				continue
			}
			arr = append(arr, node.Val)
			que = append(que, node.Left, node.Right)
		}
	}
	size := len(arr)
	for size > 0 && arr[size-1] == null {
		arr = arr[:size-1]
		size = len(arr)
	}
	result := "["
	for i, n := range arr {
		if n == null {
			result += "null"
		} else {
			result += strconv.FormatInt(int64(n), 10)
		}
		if i < size-1 {
			result += ","
		} else {
			result += "]"
		}
	}
	return result
}

func main() {
	nums := []int{1, 3, null, null, 2}
	root := buildTree(nums)
	fmt.Println(levelOrder(root))
	recoverTree(root)
	fmt.Println(levelOrder(root))

	nums = []int{3, 1, 4, null, null, 2}
	root = buildTree(nums)
	fmt.Println(levelOrder(root))
	recoverTree(root)
	fmt.Println(levelOrder(root))
}

输出:

[1,3,null,null,2]
[3,1,null,null,2]

[3,1,4,null,null,2]
[2,1,4,null,null,3]

代码2:Morris遍历

Morris遍历是一种不需要额外空间的遍历二叉树的方法,它的核心思想是利用叶子节点的空指针来存储遍历中的临时信息。对于二叉搜索树,Morris中序遍历的过程中,每个节点的左子树都已经被遍历完毕,因此可以在遍历到每个节点时,比较它的值和它的前驱节点的值,如果它的值小于前驱节点的值,那么就找到了一个逆序对。我们用两个指针first和second来记录这两个节点,最后交换它们的值即可。

package main

import (
	"fmt"
	"strconv"
)

const null = -1 << 31

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

func recoverTree(root *TreeNode) {
	var first, second, pre *TreeNode
	var temp *TreeNode
	for root != nil {
		if root.Left != nil {
			temp = root.Left
			for temp.Right != nil && temp.Right != root {
				temp = temp.Right
			}
			if temp.Right == nil {
				temp.Right = root
				root = root.Left
			} else {
				if pre != nil && root.Val < pre.Val {
					if first == nil {
						first = pre
					}
					second = root
				}
				pre = root
				temp.Right = nil
				root = root.Right
			}
		} else {
			if pre != nil && root.Val < pre.Val {
				if first == nil {
					first = pre
				}
				second = root
			}
			pre = root
			root = root.Right
		}
	}
	first.Val, second.Val = second.Val, first.Val
}

func buildTree(nums []int) *TreeNode {
	if len(nums) == 0 {
		return nil
	}
	root := &TreeNode{Val: nums[0]}
	Queue := []*TreeNode{root}
	idx := 1
	for idx < len(nums) {
		node := Queue[0]
		Queue = Queue[1:]
		if nums[idx] != null {
			node.Left = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Left)
		}
		idx++
		if idx < len(nums) && nums[idx] != null {
			node.Right = &TreeNode{Val: nums[idx]}
			Queue = append(Queue, node.Right)
		}
		idx++
	}
	return root
}

func levelOrder(root *TreeNode) string {
	if root == nil {
		return "[]"
	}
	arr := []int{}
	que := []*TreeNode{root}
	for len(que) > 0 {
		levelSize := len(que)
		for i := 0; i < levelSize; i++ {
			node := que[0]
			que = que[1:]
			if node == nil {
				arr = append(arr, null)
				continue
			}
			arr = append(arr, node.Val)
			que = append(que, node.Left, node.Right)
		}
	}
	size := len(arr)
	for size > 0 && arr[size-1] == null {
		arr = arr[:size-1]
		size = len(arr)
	}
	result := "["
	for i, n := range arr {
		if n == null {
			result += "null"
		} else {
			result += strconv.FormatInt(int64(n), 10)
		}
		if i < size-1 {
			result += ","
		} else {
			result += "]"
		}
	}
	return result
}

func main() {
	nums := []int{1, 3, null, null, 2}
	root := buildTree(nums)
	fmt.Println(levelOrder(root))
	recoverTree(root)
	fmt.Println(levelOrder(root))

	nums = []int{3, 1, 4, null, null, 2}
	root = buildTree(nums)
	fmt.Println(levelOrder(root))
	recoverTree(root)
	fmt.Println(levelOrder(root))
}

🌟 每日一练刷题专栏 🌟

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

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

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

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

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

Golang每日一练 专栏

Python每日一练 专栏

C/C++每日一练 专栏

Java每日一练 专栏

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

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

相关文章

中国人工智能企业CIMCAI世界前三大船公司落地,智能船公司产品20秒AI自动验箱,箱信息箱况+精确地点报备智慧港航中国人工智能企业

中国人工智能企业CIMCAI世界前三大船公司落地&#xff0c;智能船公司产品20秒AI自动验箱&#xff0c;箱信息箱况精确地点报备智慧港航。小程序全时全域自动化箱况检测信息识别&#xff0c;CIMCAI全球领先新一代集装箱管理方案&#xff0c;人工智能AI自动化箱信息识别箱况检测地…

Python 小型项目大全 21~25

二十一、DNA 可视化 原文&#xff1a;http://inventwithpython.com/bigbookpython/project21.html 脱氧核糖核酸是一种微小的分子&#xff0c;存在于我们身体的每个细胞中&#xff0c;包含着我们身体如何生长的蓝图。它看起来像一对核苷酸分子的双螺旋结构&#xff1a;鸟嘌呤、…

【跟着陈七一起学C语言】今天总结:C语言的函数相关知识

友情链接&#xff1a;专栏地址 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的错误&#x…

太阳能电池板AI视觉检测:不良品全程阻断,高效助力光伏扩产

2022年&#xff0c;面对复杂严峻的国内外形势&#xff0c;我国光伏行业依然实现高速增长&#xff0c;多晶硅、硅片、电池片、组件产量稳居全球首位。2023年以来&#xff0c;扩产项目已多点开花。光伏装机量天花板将不断提升&#xff0c;分布式电站占比也将逐年上升。中国光伏行…

4月软件测试面试太难,吃透这份软件测试面试笔记后,成功跳槽涨薪30K

4 月开始&#xff0c;生活工作渐渐步入正轨&#xff0c;但金三银四却没有往年顺利。昨天跟一位高级架构师的前辈聊天时&#xff0c;聊到今年的面试。有两个感受&#xff0c;一个是今年面邀的次数比往年要低不少&#xff0c;再一个就是很多面试者准备明显不足。不少候选人能力其…

python学籍管理系统

1&#xff0c;创建登陆的首页面&#xff0c;且封装起来。LoginPage.py import tkinter as tk#导入tk模块 from tkinter import messagebox#导入消息提示模块 from tkinter import messagebox from db import db #导入数据库db class LoginPage:#把整个登陆页面创建一个class类…

搭建自己的饥荒Don‘t Starve服务器-饥荒Don‘t Starve开服教程

前言 饥荒这个游戏&#xff0c;虽然首发于2016年&#xff0c;但是贵在好玩呀。和Minecraft一样&#xff0c;可玩性很高&#xff0c;并且有很多mods&#xff0c;最近和小伙伴玩的过程中&#xff0c;就想着搭建一个服务器&#xff0c;方便在主机玩家不在线时候&#xff0c;也可以…

Linux软件安装---Tomcat安装

安装Tomcat 操作步骤&#xff1a; 使用xftp上传工具将tomcat的 二进制发布包上传到Linux解压安装包&#xff0c;命令为tar -zxvf apache-tomcat*** -C /usr/local进入Tomcat的bin的启动目录&#xff0c;命令为sh startup.sh或者./startup.sh 验证Tomcat启动是否成功&#xff0…

LeetCode:376. 摆动序列——说什么贪心和动规~

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340;算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 一、&#x1f331;376. 摆动序列 题目描述&#xff1a;如果连续数字之间的差严格地在正数和…

Python 小型项目大全 46~50

# 四十六、百万骰子投掷统计模拟器 原文&#xff1a;http://inventwithpython.com/bigbookpython/project46.html 当你掷出两个六面骰子时&#xff0c;有 17%的机会掷出 7。这比掷出 2 的几率好得多&#xff1a;只有 3%。这是因为只有一种掷骰子的组合给你 2&#xff08;当两个…

「 分布式技术 」一致性哈希算法(Hash)详解

「 分布式技术 」一致性哈希算法&#xff08;Hash&#xff09;详解 参考&鸣谢 一致性 Hash 算法原理总结 kylinkzhang&#xff0c;腾讯 CSIG 后台开发工程师 什么是一致性哈希&#xff1f; xiaolinCoding 文章目录「 分布式技术 」一致性哈希算法&#xff08;Hash&#xff…

imagenet val 按类别分类

前言 有时候想看imagenet下某个类别的效果&#xff0c;但它又没划分… 之前看了这篇文章将ImageNet的验证集val数据分类到不同文件夹中&#xff0c;但不是很清楚那代码。 本文基于它的代码去做更改 把这个下下来 https://raw.githubusercontent.com/soumith/imagenetloader.…

ChatGPT 有哪些神奇的使用方式?

在遇到 ChatGPT之前&#xff0c;我很难想象&#xff0c;仅仅不到30s就能做出一个PPT。 而且对于小白来说&#xff0c;这个PPT绝对是「有水准、能拿得出手」的那种。 下面就是我用ChatGPTMindShow做的一套以分享短视频玩法为主题的 PPT&#xff0c;我挑几页大家看一下。 上面这…

10.Java面向对象----继承

Java面向对象—继承 面向对象简称 OO&#xff08;Object Oriented&#xff09;&#xff0c;20 世纪 80 年代以后&#xff0c;有了面向对象分析&#xff08;OOA&#xff09;、 面向对象设计&#xff08;OOD&#xff09;、面向对象程序设计&#xff08;OOP&#xff09;等新的系统…

2023 Java 面试题之MyBatis篇

持续更新内容涵盖&#xff1a;Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、 Linux 等技术栈&#xff08;滴滴滴.会持续更新哦&#xff0c;记得点赞、关注、分享三连击哈&#xff09;. My…

NumPy 秘籍中文第二版:十、Scikits 的乐趣

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍以下秘籍&#xff1a; 安装 scikit-learn加载示例数据集用 scikit-learn 对道琼斯股票进行聚类安装 Statsmodels使用 Statsmodels 执行…

【linux】——引导过程与服务控制

文章目录1.linux操作系统引导过程1.1 引导过程总览1.2 linux操作系统的引导过程1.3 系统初始化进程1.4 Systemd单元类型1.5 运行级别所对应的systemd目标2.排除启动类故障2.1 修复MBR扇区故障2.2 实例&#xff1a;修复MBR扇区故障2.2 修复GRUB引导故障2.3 实例&#xff1a;恢复…

电子数据取证(一)

电子数据取证概述 一&#xff0c;什么是电子数据 电子数据的特点 **1、以数字化形式存在。**所有的电子数据都是基于计算机应用和通信等电子化技术手段形成的&#xff0c;用以表示文字、图形符号、数字、字母等信息的资料。与其他证据种类不同&#xff0c;电子数据在本质上而…

Perpetuumsoft OLAP ModelKit .NET CRACK

关于 OLAP ModelKit 专业版 可视化您的数据透视表数据。OLAP ModelKit 是用 C# 编写的 .NET 多功能 OLAP 组件&#xff0c;仅包含 100% 托管代码。它具有 XP 主题外观和使用任何 .NET 数据源&#xff08;ADO.NET 和 IList&#xff09;的能力。通过在任何第三方组件&#xff08;…

java 面试消息题1-13

1. Redis 线程模型&#xff0c; 及为什么redis 这么快&#xff1f; 1.Redis虽然是一条一条处理命令的&#xff08;单线程&#xff09;&#xff0c;但是redis把每一条命令分成了很多个小命令&#xff0c;对这些小命令是多线程执行的。 2. IO 多路复用 - 可以用别人用过的IO。 …