查看: 175|回复: 8

力扣127. 单词接龙

[复制链接]
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2024-9-24 12:20 | 显示全部楼层 |阅读模式
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 中的所有字符串 互不相同
通过次数
228.5K
提交次数
465.3K
通过率
49.1%

论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
 楼主| 发表于 2024-9-24 13:11 | 显示全部楼层
把2个单词都从中间分成2个子串,存在两个子串合并后相等的,就是能转的,然后CTE接龙

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
 楼主| 发表于 2024-9-24 14:20 | 显示全部楼层
with recursive q as
(select   'hit' beginWord ,  'cog' endWord,  ['hit','hot','dot','dog','lot','log','cog'] wordList)
,a as(select unnest(wordlist)w,unnest(range(length(wordlist)))n from q where list_has(wordlist,beginWord)
union all
select unnest(wordlist+[beginWord])w,unnest(range(1+length(wordlist)))n from q where not list_has(wordlist,beginWord)
)
,t as (select a.w,b.w w2,a.n,b.n n2 from a,a b where exists(select 1 from range(1,10)t(i) where a.n<>b.n and i<=length(a.w)
and substr(a.w,1,i-1)||substr(a.w,i+1)=substr(b.w,1,i-1)||substr(b.w,i+1)))
,x as (select 1 lv, beginword b,b path,0 m from q
union all
select lv+1, w2 ,path||','||w2, m+(1<< n2) from x,t where x.b=t.w and x.b<> (select endword from q) and m & (1<<n2)=0)
from x where b=(select endword from q) order by lv limit 1;

┌───────┬─────────┬─────────────────────┬───────┐
│  lv   │    b    │        path         │   m   │
│ int32 │ varchar │       varchar       │ int32 │
├───────┼─────────┼─────────────────────┼───────┤
│     5 │ cog     │ hit,hot,lot,log,cog │   114 │
└───────┴─────────┴─────────────────────┴───────┘
Run Time (s): real 0.080 user 0.327602 sys 0.031200

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
 楼主| 发表于 2024-9-24 15:03 | 显示全部楼层
用这个测试溢出
q as
(select   '1234' beginWord ,  '9876' endWord,  [x::varchar for x in range(1234,9999)] wordList)

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
 楼主| 发表于 2024-9-24 15:15 | 显示全部楼层
如果不加lv<5,这个测试非常慢,怎么让有一个找到就退出递归?
with recursive q as
(select   '1234' beginWord ,  '2345' endWord,  [x::varchar for x in range(1234,2400)] wordList)
,a as(select unnest(wordlist)w,unnest(range(length(wordlist)))n from q where list_has(wordlist,beginWord)
union all
select unnest(wordlist+[beginWord])w,unnest(range(1+length(wordlist)))n from q where not list_has(wordlist,beginWord)
)
,t as (select a.w,b.w w2,a.n,b.n n2 from a,a b where exists(select 1 from range(1,10)t(i) where a.n<>b.n and i<=length(a.w)
and substr(a.w,1,i-1)||substr(a.w,i+1)=substr(b.w,1,i-1)||substr(b.w,i+1)))
--from t;
,x as (select 1 lv, beginword b,b path,[0] m from q
union all
select lv+1, w2 ,path||','||w2, list_append(m,n2) from x,t where lv<5 and x.b=t.w and x.b<> (select endword from q) and list_has(m ,n2)=0)
from x where b=(select endword from q) order by lv limit 1;

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
 楼主| 发表于 2024-9-24 19:44 | 显示全部楼层
找能转换的对子就要5秒
with recursive q as
(select   '1234' beginWord ,  '2345' endWord,  [x::varchar for x in range(1234,2400)] wordList)
,a as(select unnest(wordlist)w,unnest(range(length(wordlist)))n from q )
,t as (select a.w,b.w w2,a.n,b.n n2 from a,a b where exists(select 1 from range(1,10)t(i) where a.n<>b.n and i<=length(a.w)
and substr(a.w,1,i-1)||substr(a.w,i+1)=substr(b.w,1,i-1)||substr(b.w,i+1)))
select count(*) from t;

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2024-9-24 21:18 | 显示全部楼层
这个路径权重都是1, 找最短路径用递归WITH是没问题的。
如果加上权重,比如不同的字母个数之类的,那就得用Dijkstra的算法。

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2024-9-24 23:02 | 显示全部楼层
本帖最后由 newkid 于 2024-9-25 00:03 编辑




with wlist as (
select to_char(level) as w
from dual
where level>=1234
connect by level<=9999
)
,wl as (
select w
      ,level pos
      ,substr(w,level,1) c
  from wlist
connect by level<=length(w) and prior sys_guid() is not null  and prior w=w
)
,w as (
select w1.w w1,w2.w w2
  from wl w1,wl w2
where w1.pos=w2.pos and w1.c=w2.c and w1.w<>w2.w
group by w1.w,w2.w
having count(*)=max(length(w1.w))-1
)
,t(w2,path,cnt) as (
select w2,w1||','||w2,0
from w where w1='1234'
union all
select w.w2,t.path||','||w.w2
      ,count(case when w.w2='9876' then 1 end) over() cnt
  from t,w
where t.cnt=0
       and t.w2=w.w1
       and instr(t.path,w.w2)=0
)
select path from t where w2='9876' and rownum=1;


PATH
---------------------------
1234,1274,1276,9276,9876

Elapsed: 00:00:18.25

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
 楼主| 发表于 2024-9-25 05:43 来自手机 | 显示全部楼层
count()over求下轮停止很巧妙,having count(*)=length—1也节省了运算

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表