File tree Expand file tree Collapse file tree 2 files changed +88
-0
lines changed
LeetCode/剑指offer/day10_动态规划(中等)2 Expand file tree Collapse file tree 2 files changed +88
-0
lines changed Original file line number Diff line number Diff line change 1+ // 题目链接:https://leetcode.cn/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/?envType=study-plan&id=lcof
2+ // day10/31
3+ // 第 10 天主题为:动态规划(中等)
4+ // 包含两道题目:
5+ // 剑指offer46.把数字翻译成字符串
6+ // 剑指offer48.最长不含重复字符的子字符串
7+ package main
8+
9+ import "strconv"
10+
11+ //比较明显的动态规划题目,设 dp[i]代表s[:i+1]的翻译方法数目,dp[i] 明显依赖于 dp[i-1] 与 dp[i-2],类似于斐波那契数是吧,
12+ //本题有点不一样的地方在于 dp[i]=dp[i-1]+dp[i-2] 是有条件的
13+ //- 当 s[i-1] 与 s[i] 组成的数字小于 25 时,s[i] 可以与 s[i-1] 组合翻译,也可以分开翻译,dp[i]=dp[i-1]+dp[i-2],
14+ //- 否则 s[i] 与 s[i-1] 无法组合翻译,只能单独翻译,dp[i] = dp[i-1]
15+
16+ //动态规划三步骤:
17+ //- 确定dp数组大小及下标含义:dp[i] 代表 s[:i+1] 的翻译方法数目,len(dp)=len(string(num))
18+ //- dp 数组初始化:dp[0]对应s[0],单个字符只有一种翻译方法,dp[0]=1,当 s[:2] 小于26 且 s[i]!=0 时,dp[1]=2,否则 dp[1]=1
19+ //- 状态转移方程:从下标 2 开始遍历,x = strconv.Atoi(s[i-1:i+1]),并且判断 s[i-1] 是否为 0
20+ //- 若 x < 26 且 s[i-1]!= 0,dp[i]=dp[i-1]+dp[i-2],s[i] 可以与 s[i-1] 组合翻译,也可以单独翻译
21+ //- 否则,dp[i] = dp[i-1],s[i] 只能单独翻译,s[:i+1] 的翻译方法数目依赖于 s[:i]
22+ // 最后,返回 dp[n-1] 即可。
23+
24+ //有一点需要注意,在状态转移方程那里一定要判断 s[i-1] 是否为 0,因为 “01”只能翻译为 “ab”,不能翻译成 “a",
25+ //我第一次做这道题的时候就是忘记判断 s[i-1]是否为0,导致没有ac,刚才做的时候,又在这个地方跌到坑里了,有了再一再二,不会有再三再四了。
26+ func translateNum (num int ) int {
27+ s := strconv .Itoa (num )
28+ n := len (string (s ))
29+ if n == 0 {
30+ return 0
31+ }
32+ dp := make ([]int ,n )
33+ dp [0 ] = 1
34+ x ,_ := strconv .Atoi (s [:2 ])
35+ zero ,_ := strconv .Atoi (string (s [0 ]))
36+ if x < 26 && zero != 0 {
37+ dp [1 ] = 2
38+ } else {
39+ dp [1 ] = 1
40+ }
41+ for i := 2 ;i < n ;i ++ {
42+ x ,_ = strconv .Atoi (s [i - 1 :i + 1 ])
43+ zero ,_ := strconv .Atoi (string (s [i - 1 ]))
44+ if x < 26 && zero != 0 {
45+ dp [i ] = dp [i - 1 ] + dp [i - 2 ]
46+ } else {
47+ dp [i ] = dp [i - 1 ]
48+ }
49+ }
50+ return dp [n - 1 ]
51+ }
52+
Original file line number Diff line number Diff line change 1+ //题目链接:https://leetcode.cn/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/?envType=study-plan&id=lcof
2+
3+ package main
4+
5+ //我们可以用一个字典存储每个字符最近一次出现的下标
6+ //一次遍历字符串,变量 start 代表当前不含重复字符的子字符串的起始下标-1,初始化为 -1,
7+ //为什么是 -1呢,因为我们遍历第一个字符的时候,其下标为 0,为不包含重复字符的子字符串,长度为0-(-1),返回变量res初始化为 0
8+ //
9+ //一次遍历字符串,for i,x := range s ,维护 s[start+1;i+1] 为不含重复字符的子串
10+ //若当前遍历到的字符的最近一次出现下标大于 start(不会出现等于的情况),说明当前加入当前字符后,该字符串将包含重复字符,
11+ //我们的做法是,将 start 更新到其最近一次出现的下标,这样就保证了加入当前字符后,我们目前的子字符串仍然不包含重复字符,
12+ //
13+ //否则(小于 start 或者 该字符在字符串中是第一次出现),当前不含重复字符的子串长度增加,更新 res 变量,
14+
15+ //最后,更新当前字符的最近出现下标。
16+ func lengthOfLongestSubstring (s string ) int {
17+ start := - 1
18+ record := map [rune ]int {}
19+ res := 0
20+ for i ,x := range s {
21+ if _ ,ok := record [x ];ok && record [x ] > start {
22+ start = record [x ]
23+ } else {
24+ res = max (res ,i - start )
25+ }
26+ record [x ] = i
27+ }
28+ return res
29+ }
30+
31+ func max (x ,y int ) int {
32+ if x > y {
33+ return x
34+ }
35+ return y
36+ }
You can’t perform that action at this time.
0 commit comments