【华为机试】127. 单词接龙

文章目录

  • 127. 单词接龙
    • 描述
    • 示例 1:
    • 示例 2:
    • 提示:
    • 解题思路
      • 算法分析
      • 问题本质分析
      • 单向BFS算法详解
      • 双向BFS算法详解
      • 邻居单词生成过程
      • 算法流程图
      • 边界情况分析
      • 各种解法对比
      • 时间复杂度分析
      • 空间复杂度分析
      • 关键优化点
      • 实际应用场景
      • 图构建策略
      • 双向BFS优化细节
      • 测试用例设计
      • 算法扩展
      • 代码实现要点
      • 手工验证示例
    • 完整题解代码

127. 单词接龙

描述

字典 wordList 中从单词 beginWord 到 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk:

每一对相邻的单词只差一个字母。
对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
sk == endWord
给你两个单词 beginWord 和 endWord 和一个字典 wordList ,返回 从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0 。

示例 1:

输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
输出:5
解释:一个最短转换序列是 “hit” -> “hot” -> “dot” -> “dog” -> “cog”, 返回它的长度 5。

示例 2:

输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”]
输出:0
解释:endWord “cog” 不在字典中,所以无法进行转换。

提示:

  • 1 <= beginWord.length <= 10
  • endWord.length == beginWord.length
  • 1 <= wordList.length <= 5000
  • wordList[i].length == beginWord.length
  • beginWord、endWord 和 wordList[i] 由小写英文字母组成
  • beginWord != endWord
  • wordList 中的所有字符串 互不相同

解题思路

算法分析

这道题是图的最短路径BFS广度优先搜索的经典应用。主要解法包括:

  1. 单向BFS:从起点开始广度优先搜索
  2. 双向BFS:从起点和终点同时搜索
  3. A*搜索:启发式搜索算法
  4. Dijkstra算法:适用于加权图的最短路径

问题本质分析

graph TDA[单词接龙] --> B[图的最短路径问题]B --> C[单向BFS]B --> D[双向BFS]B --> E[A*搜索]C --> F[从起点层层扩展]D --> G[两端同时搜索]E --> H[启发式函数引导]F --> I[时间复杂度O_N²×M]G --> J[时间复杂度O_N×M]H --> K[时间复杂度优化]

单向BFS算法详解

输入beginWord和endWord
检查endWord是否在wordList中
endWord存在?
返回0
初始化队列和访问集合
将beginWord加入队列
BFS层次遍历
队列为空?
返回0 - 无法到达
取出当前层所有单词
对每个单词尝试变换
枚举每个位置的26个字母
新单词在wordList中?
继续下一个变换
新单词是endWord?
返回当前层数+1
加入队列和访问集合
当前单词所有位置遍历完?
当前层所有单词处理完?
层数+1

双向BFS算法详解

flowchart TDA[双向BFS初始化] --> B[创建正向和反向搜索集合]B --> C[beginSet = {beginWord}]C --> D[endSet = {endWord}]D --> E[visited = 空集合]E --> F{beginSet和endSet都非空?}F -->|否| G[返回0]F -->|是| H{beginSet与endSet有交集?}H -->|是| I[返回当前层数]H -->|否| J[选择较小的集合扩展]J --> K[遍历当前集合中的每个单词]K --> L[生成所有可能的邻居]L --> M{邻居在对方集合中?}M -->|是| N[找到连接路径]M -->|否| O{邻居未被访问?}O -->|是| P[加入下一层集合]O -->|否| Q[跳过此邻居]P --> R[标记为已访问]Q --> LR --> LL --> S{当前单词所有邻居处理完?}S -->|否| LS -->|是| T{当前集合所有单词处理完?}T -->|否| KT -->|是| U[更新当前集合为下一层]U --> V[层数+1]V --> FN --> W[返回总层数]

邻居单词生成过程

邻居单词生成
遍历单词每个位置
保存原字符
尝试26个字母替换
新单词在字典中?
添加到邻居列表
跳过此字母
恢复原字符
所有字母尝试完?
所有位置处理完?
返回邻居列表

算法流程图

开始
输入验证
endWord在wordList中?
返回0
选择搜索算法
单向BFS
双向BFS
从beginWord开始层次遍历
从两端同时搜索
生成邻居单词
找到目标单词?
返回路径长度
还有未访问单词?
继续搜索下一层
返回0 - 无路径

边界情况分析

边界情况
endWord不在字典中
beginWord等于endWord
字典为空
无法到达
只差一个字母
直接返回0
返回1或处理特殊情况
返回0
BFS遍历完无结果
返回2

各种解法对比

graph TDA[解法对比] --> B[单向BFS]A --> C[双向BFS]A --> D[A*搜索]A --> E[DFS回溯]B --> F[时间O_N²×M空间O_N×M]C --> G[时间O_N×M空间O_N×M]D --> H[时间优化空间O_N×M]E --> I[时间指数级空间O_深度]F --> J[简单直观推荐]G --> K[性能最优推荐]H --> L[复杂实现适合研究]I --> M[不适合此问题]

时间复杂度分析

  • 单向BFS:O(N² × M),N为单词数,M为单词长度
  • 双向BFS:O(N × M),搜索空间减半
  • A*搜索:O(N × M × log N),依赖启发函数
  • DFS回溯:O(N!),指数级时间复杂度

空间复杂度分析

  • 单向BFS:O(N × M),队列和访问集合
  • 双向BFS:O(N × M),两个搜索集合
  • A*搜索:O(N × M),优先队列和访问记录
  • DFS回溯:O(深度 × M),递归栈空间

关键优化点

优化策略
双向搜索
字典预处理
邻居缓存
启发式函数
搜索空间减半
快速邻居查找
避免重复计算
引导搜索方向
性能提升

实际应用场景

应用场景
自然语言处理
游戏开发
网络路由
社交网络
词汇语义距离
路径寻找算法
最短路径路由
社交关系链
核心算法组件

图构建策略

图构建方法
邻接表
模式匹配
在线生成
预构建所有连接
通配符模式匹配
动态生成邻居
空间换时间
中间节点优化
时间换空间

双向BFS优化细节

双向BFS优化
始终扩展较小集合
减少分支因子
提前终止条件
内存优化
集合大小比较
选择扩展方向
平衡搜索树
及时清理无用节点
复用数据结构

测试用例设计

测试用例
基础功能
边界情况
性能测试
正常转换
单步转换
多步转换
无法到达
目标不在字典
相同起止点
大字典测试
长单词测试
验证正确性
验证性能

算法扩展

算法扩展
单词接龙II
最小基因变化
开锁问题
迷宫问题
返回所有最短路径
基因序列变换
密码锁状态转换
二维网格路径
图搜索问题家族

代码实现要点

  1. 图的表示

    • 使用邻接表或在线生成邻居
    • 字典可以用Set进行快速查找
    • 考虑内存和时间的平衡
  2. BFS实现细节

    • 使用队列进行层次遍历
    • 记录访问状态避免重复
    • 正确处理层数计算
  3. 双向BFS优化

    • 始终扩展较小的集合
    • 及时检测两个搜索的交集
    • 合理的终止条件
  4. 邻居生成策略

    • 枚举每个位置的所有可能字符
    • 利用字典进行有效性检查
    • 避免生成已访问的单词

手工验证示例

graph TDA["hit → cog 示例"] --> B[层次0: hit]B --> C[层次1: hot]C --> D[层次2: dot, lot]D --> E[层次3: dog, log]E --> F[层次4: cog]F --> G[路径长度 = 5]H[双向BFS] --> I[正向: hit → hot → dot]H --> J[反向: cog ← dog ← dot]I --> K[在dot处相遇]J --> KK --> L[总长度 = 3 + 2 = 5]

这个问题的关键在于理解图的最短路径本质掌握BFS层次遍历技巧,通过合适的搜索策略找到从起始单词到目标单词的最短变换序列。

完整题解代码

package mainimport ("fmt""strings""time"
)// 解法一:单向BFS(经典解法)
// 时间复杂度:O(N²×M),空间复杂度:O(N×M)
func ladderLength(beginWord string, endWord string, wordList []string) int {// 特殊情况:起点等于终点if beginWord == endWord {return 1}// 将wordList转换为set以便快速查找wordSet := make(map[string]bool)for _, word := range wordList {wordSet[word] = true}// 如果endWord不在wordList中,无法到达if !wordSet[endWord] {return 0}// BFS队列和访问记录queue := []string{beginWord}visited := make(map[string]bool)visited[beginWord] = truelevel := 1for len(queue) > 0 {size := len(queue)// 处理当前层的所有单词for i := 0; i < size; i++ {current := queue[i]// 生成所有可能的邻居单词neighbors := getNeighbors(current, wordSet)for _, neighbor := range neighbors {if neighbor == endWord {return level + 1}if !visited[neighbor] {visited[neighbor] = truequeue = append(queue, neighbor)}}}// 更新队列为下一层queue = queue[size:]level++}return 0
}// 生成所有有效的邻居单词
func getNeighbors(word string, wordSet map[string]bool) []string {var neighbors []stringchars := []rune(word)for i := 0; i < len(chars); i++ {original := chars[i]// 尝试26个字母for c := 'a'; c <= 'z'; c++ {if c == original {continue}chars[i] = cnewWord := string(chars)if wordSet[newWord] {neighbors = append(neighbors, newWord)}}chars[i] = original // 恢复原字符}return neighbors
}// 解法二:双向BFS(优化解法)
// 时间复杂度:O(N×M),空间复杂度:O(N×M)
func ladderLengthBidirectional(beginWord string, endWord string, wordList []string) int {// 特殊情况:起点等于终点if beginWord == endWord {return 1}wordSet := make(map[string]bool)for _, word := range wordList {wordSet[word] = true}if !wordSet[endWord] {return 0}// 双向搜索集合beginSet := make(map[string]bool)endSet := make(map[string]bool)beginSet[beginWord] = trueendSet[endWord] = truevisited := make(map[string]bool)level := 1for len(beginSet) > 0 && len(endSet) > 0 {// 优化:始终扩展较小的集合if len(beginSet) > len(endSet) {beginSet, endSet = endSet, beginSet}nextSet := make(map[string]bool)for word := range beginSet {neighbors := getNeighbors(word, wordSet)for _, neighbor := range neighbors {// 如果在对方集合中找到,说明路径连通if endSet[neighbor] {return level + 1}// 如果未访问过,加入下一层if !visited[neighbor] {visited[neighbor] = truenextSet[neighbor] = true}}}beginSet = nextSetlevel++}return 0
}// 解法三:使用模式匹配优化的BFS
// 时间复杂度:O(N×M),空间复杂度:O(N×M)
func ladderLengthPattern(beginWord string, endWord string, wordList []string) int {if beginWord == endWord {return 1}// 构建模式到单词的映射patterns := make(map[string][]string)for _, word := range wordList {for i := 0; i < len(word); i++ {pattern := word[:i] + "*" + word[i+1:]patterns[pattern] = append(patterns[pattern], word)}}// 也要为beginWord建立模式for i := 0; i < len(beginWord); i++ {pattern := beginWord[:i] + "*" + beginWord[i+1:]patterns[pattern] = append(patterns[pattern], beginWord)}// BFSqueue := []string{beginWord}visited := make(map[string]bool)visited[beginWord] = truelevel := 1for len(queue) > 0 {size := len(queue)for i := 0; i < size; i++ {current := queue[i]// 通过模式找到所有邻居for j := 0; j < len(current); j++ {pattern := current[:j] + "*" + current[j+1:]for _, neighbor := range patterns[pattern] {if neighbor == endWord {return level + 1}if !visited[neighbor] && neighbor != current {visited[neighbor] = truequeue = append(queue, neighbor)}}}}queue = queue[size:]level++}return 0
}// 解法四:A*搜索算法
// 时间复杂度:O(N×M×log N),空间复杂度:O(N×M)
func ladderLengthAStar(beginWord string, endWord string, wordList []string) int {wordSet := make(map[string]bool)for _, word := range wordList {wordSet[word] = true}if !wordSet[endWord] {return 0}// 启发式函数:计算两个单词的差异字符数heuristic := func(word1, word2 string) int {diff := 0for i := 0; i < len(word1); i++ {if word1[i] != word2[i] {diff++}}return diff}// 优先队列节点type Node struct {word stringg    int // 从起点到当前节点的实际距离f    int // g + h(启发式距离)}// 简化的优先队列实现var pq []Node// 添加起始节点start := Node{word: beginWord,g:    0,f:    heuristic(beginWord, endWord),}pq = append(pq, start)visited := make(map[string]int)visited[beginWord] = 0for len(pq) > 0 {// 简单的优先队列:找f值最小的节点minIdx := 0for i := 1; i < len(pq); i++ {if pq[i].f < pq[minIdx].f {minIdx = i}}current := pq[minIdx]pq = append(pq[:minIdx], pq[minIdx+1:]...)if current.word == endWord {return current.g + 1}neighbors := getNeighbors(current.word, wordSet)for _, neighbor := range neighbors {newG := current.g + 1if prevG, exists := visited[neighbor]; !exists || newG < prevG {visited[neighbor] = newGnode := Node{word: neighbor,g:    newG,f:    newG + heuristic(neighbor, endWord),}pq = append(pq, node)}}}return 0
}// 解法五:DFS + 记忆化(递归回溯)
// 时间复杂度:O(N!),空间复杂度:O(N×M + 深度)
func ladderLengthDFS(beginWord string, endWord string, wordList []string) int {wordSet := make(map[string]bool)for _, word := range wordList {wordSet[word] = true}if !wordSet[endWord] {return 0}memo := make(map[string]int)visited := make(map[string]bool)var dfs func(word string) intdfs = func(word string) int {if word == endWord {return 1}if val, exists := memo[word]; exists {return val}visited[word] = trueminLen := 0neighbors := getNeighbors(word, wordSet)for _, neighbor := range neighbors {if !visited[neighbor] {length := dfs(neighbor)if length > 0 {if minLen == 0 || length+1 < minLen {minLen = length + 1}}}}visited[word] = falsememo[word] = minLenreturn minLen}return dfs(beginWord)
}// 测试函数
func testLadderLength() {testCases := []struct {beginWord stringendWord   stringwordList  []stringexpected  intdesc      string}{{"hit", "cog",[]string{"hot", "dot", "dog", "lot", "log", "cog"},5, "示例1:标准转换路径",},{"hit", "cog",[]string{"hot", "dot", "dog", "lot", "log"},0, "示例2:目标不在字典中",},{"a", "c",[]string{"a", "b", "c"},2, "简单单字母转换",},{"hot", "dog",[]string{"hot", "dog", "dot"},3, "两步转换",},{"hot", "dog",[]string{"hot", "dog"},0, "无中间路径",},{"leet", "code",[]string{"lest", "leet", "lose", "code", "lode", "robe", "lost"},6, "复杂路径",},{"hit", "hit",[]string{"hit"},1, "起点等于终点",},{"qa", "sq",[]string{"si", "go", "se", "cm", "so", "ph", "mt", "db", "mb", "sb", "kr", "ln", "tm", "le", "av", "sm", "ar", "ci", "ca", "br", "ti", "ba", "to", "ra", "fa", "yo", "ow", "sn", "ya", "cr", "po", "fe", "ho", "ma", "re", "or", "rn", "au", "ur", "rh", "sr", "tc", "lt", "lo", "as", "fr", "nb", "yb", "if", "pb", "ge", "th", "pm", "rb", "sh", "co", "ga", "li", "ha", "hz", "no", "bi", "di", "hi", "qa", "pi", "os", "uh", "wm", "an", "me", "mo", "na", "la", "st", "er", "sc", "ne", "mn", "mi", "am", "ex", "pt", "io", "be", "fm", "ta", "tb", "ni", "mr", "pa", "he", "lr", "sq", "ye"},5, "大字典测试",},}fmt.Println("=== 单词接龙测试 ===")fmt.Println()for i, tc := range testCases {// 测试主要解法result1 := ladderLength(tc.beginWord, tc.endWord, tc.wordList)result2 := ladderLengthBidirectional(tc.beginWord, tc.endWord, tc.wordList)result3 := ladderLengthPattern(tc.beginWord, tc.endWord, tc.wordList)status := "✅"if result1 != tc.expected {status = "❌"}fmt.Printf("测试 %d: %s\n", i+1, tc.desc)fmt.Printf("输入: beginWord=\"%s\", endWord=\"%s\"\n", tc.beginWord, tc.endWord)fmt.Printf("字典: %v\n", tc.wordList)fmt.Printf("期望: %d\n", tc.expected)fmt.Printf("单向BFS: %d\n", result1)fmt.Printf("双向BFS: %d\n", result2)fmt.Printf("模式匹配: %d\n", result3)fmt.Printf("结果: %s\n", status)fmt.Println(strings.Repeat("-", 50))}
}// 性能测试
func benchmarkLadderLength() {fmt.Println()fmt.Println("=== 性能测试 ===")fmt.Println()// 构造测试数据testData := []struct {beginWord stringendWord   stringwordList  []stringdesc      string}{{"hit", "cog",[]string{"hot", "dot", "dog", "lot", "log", "cog"},"小字典测试",},{"qa", "sq",generateLargeWordList(100, 2),"中等字典测试",},{"start", "enddd",generateLargeWordList(500, 5),"大字典测试",},}algorithms := []struct {name stringfn   func(string, string, []string) int}{{"单向BFS", ladderLength},{"双向BFS", ladderLengthBidirectional},{"模式匹配", ladderLengthPattern},{"A*搜索", ladderLengthAStar},}for _, data := range testData {fmt.Printf("%s (字典大小: %d):\n", data.desc, len(data.wordList))for _, algo := range algorithms {start := time.Now()result := algo.fn(data.beginWord, data.endWord, data.wordList)duration := time.Since(start)fmt.Printf("  %s: 结果=%d, 耗时: %v\n", algo.name, result, duration)}fmt.Println()}
}// 生成大规模测试词典
func generateLargeWordList(size, wordLen int) []string {words := make([]string, 0, size)// 生成一些相关的单词base := strings.Repeat("a", wordLen)words = append(words, base)for i := 1; i < size; i++ {word := []rune(base)// 随机改变1-2个字符changes := 1 + i%2for j := 0; j < changes; j++ {pos := (i + j) % wordLenword[pos] = rune('a' + (i+j)%26)}words = append(words, string(word))}return words
}// 演示BFS搜索过程
func demonstrateBFS() {fmt.Println("\n=== BFS搜索过程演示 ===")beginWord := "hit"endWord := "cog"wordList := []string{"hot", "dot", "dog", "lot", "log", "cog"}fmt.Printf("从 \"%s\" 到 \"%s\" 的转换过程:\n", beginWord, endWord)fmt.Printf("字典: %v\n\n", wordList)// 演示搜索层次wordSet := make(map[string]bool)for _, word := range wordList {wordSet[word] = true}queue := []string{beginWord}visited := make(map[string]bool)visited[beginWord] = truelevel := 1fmt.Printf("层次 %d: %v\n", level, queue)for len(queue) > 0 && level <= 5 {size := len(queue)nextLevel := []string{}for i := 0; i < size; i++ {current := queue[i]neighbors := getNeighbors(current, wordSet)for _, neighbor := range neighbors {if neighbor == endWord {fmt.Printf("层次 %d: 找到目标 %s!\n", level+1, neighbor)fmt.Printf("路径长度: %d\n", level+1)return}if !visited[neighbor] {visited[neighbor] = truenextLevel = append(nextLevel, neighbor)}}}if len(nextLevel) > 0 {queue = nextLevellevel++fmt.Printf("层次 %d: %v\n", level, queue)} else {break}}
}// 演示双向BFS
func demonstrateBidirectionalBFS() {fmt.Println("\n=== 双向BFS演示 ===")beginWord := "hit"endWord := "cog"wordList := []string{"hot", "dot", "dog", "lot", "log", "cog"}fmt.Printf("双向搜索从 \"%s\" 和 \"%s\" 同时开始\n", beginWord, endWord)wordSet := make(map[string]bool)for _, word := range wordList {wordSet[word] = true}beginSet := map[string]bool{beginWord: true}endSet := map[string]bool{endWord: true}visited := make(map[string]bool)level := 1fmt.Printf("层次 %d: 正向=%v, 反向=%v\n", level, getKeys(beginSet), getKeys(endSet))for len(beginSet) > 0 && len(endSet) > 0 && level <= 3 {if len(beginSet) > len(endSet) {beginSet, endSet = endSet, beginSetfmt.Println("交换搜索方向")}nextSet := make(map[string]bool)for word := range beginSet {neighbors := getNeighbors(word, wordSet)for _, neighbor := range neighbors {if endSet[neighbor] {fmt.Printf("层次 %d: 在 %s 处相遇!\n", level+1, neighbor)fmt.Printf("总路径长度: %d\n", level+1)return}if !visited[neighbor] {visited[neighbor] = truenextSet[neighbor] = true}}}beginSet = nextSetlevel++if len(beginSet) > 0 {fmt.Printf("层次 %d: 当前扩展=%v, 对方=%v\n", level, getKeys(beginSet), getKeys(endSet))}}
}// 辅助函数:获取map的所有键
func getKeys(m map[string]bool) []string {keys := make([]string, 0, len(m))for k := range m {keys = append(keys, k)}return keys
}func main() {fmt.Println("127. 单词接龙 - 多种解法实现")fmt.Println("=====================================")// 基础功能测试testLadderLength()// 性能对比测试benchmarkLadderLength()// BFS过程演示demonstrateBFS()// 双向BFS演示demonstrateBidirectionalBFS()// 展示算法特点fmt.Println("\n=== 算法特点分析 ===")fmt.Println("1. 单向BFS:经典解法,层次遍历,简单直观")fmt.Println("2. 双向BFS:从两端搜索,搜索空间减半,性能最优")fmt.Println("3. 模式匹配:预处理优化邻居查找,减少重复计算")fmt.Println("4. A*搜索:启发式搜索,适合有明确目标的场景")fmt.Println("5. DFS回溯:递归实现,但时间复杂度较高")fmt.Println("\n=== 关键技巧总结 ===")fmt.Println("• 图的建模:将单词看作图中的节点,差一个字母的单词相连")fmt.Println("• BFS层次遍历:保证找到的第一个路径是最短的")fmt.Println("• 双向优化:从两端同时搜索,显著减少搜索空间")fmt.Println("• 访问控制:避免重复访问和环路问题")fmt.Println("• 集合操作:使用Set进行快速查找和去重")
}

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

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

相关文章

仿艾莫迅MODBUS调试工具写一个上位机

公司采购了一个夹具&#xff0c;项目负责人想要试探这个夹具的性能&#xff0c;于是想要我这边写一个烤机的程序&#xff0c;小编结合官网资料 https://wiki.amsamotion.com/?title196&doc222查看其pdf说明文档和调试工具并按照其工具写一个烤机上位机根据项目负责人的要求…

云展厅:开启数字化展示新时代

在科技飞速发展的今天&#xff0c;数字化浪潮正席卷各个行业&#xff0c;展览展示领域也不例外。云展厅作为一种全新的展览形式&#xff0c;正逐渐崭露头角&#xff0c;以其独特的优势和创新的技术应用&#xff0c;为观众带来前所未有的观展体验&#xff0c;也为企业和机构提供…

硬件电路基础学习

一、基础元器件学习 1、电阻 1.1 作用 电阻的工作原理是基于欧姆定律&#xff0c;即电阻的阻值取决于其材料、长度和横截面积。电阻的主要作用是限制电流&#xff0c;调节电压和电流&#xff0c;以及保护电路。1.2 数值计算 欧姆定律 通过欧姆定律计算所需保护电阻的大小注意…

基于C++和人工智能(DeepSeek)实践

基于C++和人工智能(如DeepSeek)实践 以下是基于C++和人工智能(如DeepSeek或其他AI框架)的实际应用示例,涵盖不同领域和技术方向,供参考: 基于C++和人工智能(如DeepSeek或其他AI框架)的实际应用示例 图像识别与处理 人脸检测:使用OpenCV和DNN模块加载预训练的Caffe…

书生浦语第五期L0G1000

完成 视频课程学习&#xff0c;并在 https://chat.intern-ai.org.cn/ 平台中实践提示词技巧&#xff0c;与 InternLM 和 InternVL 各完成 10 次对话记录在飞书文档中。 参加 浦语提示词工程论文分类打榜赛&#xff0c;分数超过 40 分 InternLM InternVL 浦语提示词工程论文分…

SpringCloud(一)微服务基础认识

1、介绍微服务架构是一种架构模式&#xff0c;它提倡将原本独立的单体应用&#xff0c;拆分成多个小型服务。这些小型服务各 自独立运行&#xff0c;服务与服务间的通信采用轻量级通信机制&#xff08;一般基于HTTP协议的RESTful API&#xff09; &#xff0c;达到互相协调、互…

MaxKB+MinerU:通过API实现PDF文档解析并存储至知识库

MinerU是一款开源的高质量数据提取工具&#xff0c;能够将PDF文档转换为Markdown和JSON格式。2025年6月13日&#xff0c;MinerU发布了v2.0版本&#xff0c;相较于v1.0版本实现了架构和功能的全面重构与升级。在优化代码结构和交互方式的同时&#xff0c;v2.0版本还集成了小参数…

一文了解 `package.json` 和 `package-lock.json`文件

所有使用 npm 或 yarn&#xff08;部分场景&#xff09;管理依赖的 JavaScript/Node.js 项目都会存在**的核心文件–package.json 和 package-lock.json&#xff0c;无论项目类型是 Vue、React、Angular&#xff0c;还是纯 Node.js 后端项目、普通 JavaScript 工具库等。 所以这…

【AI论文】大语言模型量化的几何原理:将GPTQ视为Babai最近平面算法

摘要&#xff1a;将大型语言模型&#xff08;LLMs&#xff09;的权重从16位量化到更低位宽&#xff0c;是实际部署大规模Transformer模型到更具性价比的加速器上的通用方法。GPTQ已成为大语言模型规模下一站式训练后量化的标准方法之一。然而&#xff0c;其内部工作原理被描述为…

数据处理四件套:NumPy/Pandas/Matplotlib/Seaborn速通指南

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠。 数据清洗 特征可视化 Kaggle数据集实操 读者收获&#xff1a;1周内具备数据预处理能力 数…

计算机系统层次结构

计算机系统通过多层抽象&#xff0c;平衡硬件效率与软件灵活性&#xff0c;各层以独立语言和功能构成有机整体。一、层次划分&#xff08;从底层到顶层&#xff09;层级名称特点实现方式第1级微程序机器层硬件直接执行微指令&#xff08;如微操作控制信号&#xff09;。物理硬件…

04 基于sklearn的机械学习-梯度下降(上)

梯度下降一 、为什么要用到梯度下降&#xff1f;正规方程的缺陷&#xff1a;非凸函数问题&#xff1a;损失函数非凸时&#xff0c;导数为0会得到多个极值点&#xff08;非唯一解&#xff09;计算效率低&#xff1a;逆矩阵运算时间复杂度 O(n3)&#xff0c;特征量翻倍时计算时间…

淘宝 API HTTP/2 多路复用与连接优化实践:提升商品数据采集吞吐量

一、引言​随着电商行业的蓬勃发展&#xff0c;对淘宝平台商品数据的采集需求日益增长。无论是市场调研公司分析市场趋势、电商平台整合商品资源&#xff0c;还是商家进行竞品分析&#xff0c;都需要高效、稳定地获取大量淘宝商品数据。然而&#xff0c;传统的 HTTP 协议在面对…

javascript中call、apply 和 bind 的区别详解

文章目录深入浅出&#xff1a;JavaScript 中的 call、apply 和 bind一、三位魔法师的共同使命二、各显神通的魔法师们1. call - 即时通讯专家2. apply - 批量处理高手3. bind - 预约服务大师三、魔法师们的对比表格四、魔法师们的实际应用1. 借用方法2. 函数柯里化3. 事件处理五…

【PHP】接入百度AI开放平台人脸识别API,实现人脸对比

目录 一、需求 二、准备工作 1、申请服务 2、创建应用&#xff0c;获取开发密钥 3、官方开发文档 4、测试人像图片 三、PHP接入 1、鉴权&#xff0c;获取access_token 2、人脸对比 四、完整代码 一、需求 现在人脸识别、人脸对比技术越来越成熟&#xff0c;使用越来越…

【东枫科技】DreamHAT+

DreamHAT 是一款顶部附加硬件 (HAT) 套件&#xff0c;可为 Raspberry Pi 提供 60GHz 毫米波雷达供您使用。 全尺寸 HAT 包含一个英飞凌 BGT60TR13C 芯片&#xff0c;具有单个发射天线和三个接收器&#xff08;TX/RX&#xff09;&#xff0c;通过 GPIO 引脚和 SPI 连接到 Raspbe…

Spring Boot + MongoDB:从零开始手动配置 MongoConfig 实战

前言 你以为只要写上 spring.data.mongodb.*,就能一劳永逸,MongoDB 立马听话?别天真,这只是入门级操作,像是拿个自动挡钥匙,开个小车溜达溜达,远远算不上高手操作。当项目需求变得复杂,连接字符串需要灵活配置,或者多数据源并行作战时,自动配置的魔法显得捉襟见肘。…

建筑节能目标下,楼宇自控系统以高效运行助力节能减碳

随着全球气候变化问题日益严峻&#xff0c;节能减排已成为各国政府和企业的重要任务。在建筑领域&#xff0c;楼宇自控系统&#xff08;Building Automation System, BAS&#xff09;作为实现建筑节能目标的关键技术&#xff0c;正发挥着越来越重要的作用。根据中国政府发布的《…

LOVON——面向足式Open-Vocabulary的VLN导航:LLM做任务分解、YOLO11做目标检测,最后L2MM将指令和视觉映射为动作,且解决动态模糊

前言 因为项目需要(比如我们在做的两个展厅讲解订单)&#xff0c;近期我一直在研究VLN相关&#xff0c;有些工作哪怕暂时还没开源(将来可能会开源)&#xff0c;但也依然会解读&#xff0c;比如好处之一是构建完整的VLN知识体系&#xff0c;本文便是其中一例 我在解读过程中&am…

在线免费的AI文本转语音工具TTSMaker介绍

TTSMaker是一个在线的文本转语音工具&#xff0c; 支持多语言和中文方言&#xff0c;不同的语言和方言单次转换的字符上限从200-10000 不同&#xff0c;转换的效果还不错&#xff0c;听不出明显的AI痕迹。 工具的网址是&#xff1a;https://ttsmaker.cn/。 工具的界面如上&…