File tree Expand file tree Collapse file tree 4 files changed +222
-17
lines changed
Expand file tree Collapse file tree 4 files changed +222
-17
lines changed Original file line number Diff line number Diff line change 77
88* [ 剑指 Offer] ( docs/jzof/README.md )
99 * [ OF3.数组中重复的数字] ( docs/jzof/of003.md )
10+ * [ OF4. 二维数组中的查找] ( docs/jzof/of004.md )
11+ * [ OF5. 替换空格] ( docs/jzof/of005.md )
1012 * [ OF37.序列化二叉树] ( docs/jzof/of037.md )
1113 * [ OF14-I.剪绳子] ( docs/jzof/of014-i.md )
1214 * [ OF14-II.剪绳子] ( docs/jzof/of014-ii.md )
Original file line number Diff line number Diff line change 1+ ---
2+ description : 剑指 Offer 04. 二维数组中的查找
3+ ---
4+
5+ # OF4. 二维数组中的查找
6+
7+ ## 题目描述
8+
9+ [ 题目地址] ( https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/ )
10+
11+ 在一个 n \* m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
12+
13+ ### ** 示例 1:**
14+
15+ ``` go
16+ 输入:
17+ [
18+ [1 , 4 , 7 , 11 , 15 ],
19+ [2 , 5 , 8 , 12 , 19 ],
20+ [3 , 6 , 9 , 16 , 22 ],
21+ [10 , 13 , 14 , 17 , 24 ],
22+ [18 , 21 , 23 , 26 , 30 ]
23+ ]
24+ 给定 target = 5 ,返回 true 。
25+ 给定 target = 20 ,返回 false 。
26+ ```
27+
28+ ## 题解
29+
30+ ### 思路1 : 线性查找
31+
32+ 由于给定的二维数组具备每行从左到右递增以及每列从上到下递增的特点,当访问到一个元素时,可以排除数组中的部分元素。
33+
34+ 从二维数组的右上角开始查找。如果当前元素等于目标值,则返回 true。如果当前元素大于目标值,则移到左边一列。如果当前元素小于目标值,则移到下边一行。
35+
36+ 可以证明这种方法不会错过目标值。如果当前元素大于目标值,说明当前元素的下边的所有元素都一定大于目标值,因此往下查找不可能找到目标值,往左查找可能找到目标值。如果当前元素小于目标值,说明当前元素的左边的所有元素都一定小于目标值,因此往左查找不可能找到目标值,往下查找可能找到目标值。
37+
38+ ** 算法流程:**
39+
40+ 1 . 若数组为空,返回 false
41+ 2 . 初始化行下标为 0,列下标为二维数组的列数减 1
42+ 3 . 重复下列步骤,直到行下标或列下标超出边界
43+ 1 . 获得当前下标位置的元素 num
44+ 2 . 如果 num 和 target 相等,返回 true
45+ 3 . 如果 num 大于 target,列下标减 1
46+ 4 . 如果 num 小于 target,行下标加 1
47+ 4 . 循环体执行完毕仍未找到元素等于 target ,说明不存在这样的元素,返回 false\`
48+
49+ 作者:
50+
51+ ** 复杂度分析:**
52+
53+ * ** 时间复杂度** $$ O(M+N) $$ ** :** 访问到的下标的行最多增加 ` n ` 次,列最多减少 ` m ` 次,因此循环体最多执行 ` n + m ` 次
54+ * ** 空间复杂度** $$ O(1) $$ ** :**
55+
56+ #### 代码
57+
58+ {% tabs %}
59+ {% tab title="Go" %}
60+ ``` go
61+ func findNumberIn2DArray (matrix [][]int , target int ) bool {
62+ if len (matrix) == 0 {
63+ return false
64+ }
65+ rLen := len (matrix)
66+ cLen := len (matrix[0 ])
67+
68+ // 从右上角的元素找起来
69+ for r , c := 0 , cLen-1 ; r < rLen && c >= 0 ; {
70+ if matrix[r][c] == target {
71+ return true
72+ }
73+ if matrix[r][c] > target {
74+ c--
75+ } else {
76+ r++
77+ }
78+ }
79+ return false
80+ }
81+ ```
82+ {% endtab %}
83+ {% endtabs %}
84+
85+ ###
86+
87+ ## 总结
88+
89+ 如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[ awesome-golang-algorithm] ( https://github.com/kylesliu/awesome-golang-algorithm )
90+
Original file line number Diff line number Diff line change 1+ ---
2+ description : 剑指 Offer 05. 替换空格
3+ ---
4+
5+ # OF5. 替换空格
6+
7+ ## 题目描述
8+
9+ [ 题目地址] ( https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/ )
10+
11+ 请实现一个函数,把字符串 ` s ` 中的每个空格替换成"%20"。
12+
13+ ### ** 示例 1:**
14+
15+ ``` go
16+ 输入:s = " We are happy."
17+ 输出:" We%20a re%20h appy."
18+ ```
19+
20+ ### ** 限制:**
21+
22+ ``` go
23+ 0 <= s 的长度 <= 10000
24+ ```
25+
26+ ## 题解
27+
28+ ### 思路1 : 遍历添加
29+
30+ Python 和 Golang 的字符串都是不是修改的,不考虑内存的话可以开个数组方便操作。
31+
32+ ** 算法流程:**
33+
34+ 1 . 初始化一个数组
35+ 2 . 循环遍历字符串
36+ 1 . 如果 v = 空格:后缀添加 ` %20 `
37+ 2 . 如果 v != 空格:后缀添加 ` v `
38+ 3 . 数组转化为字符串
39+
40+ ** 复杂度分析:**
41+
42+ * ** 时间复杂度** $$ O(N) $$ ** :** 遍历字符串 ` s ` 一遍。
43+ * ** 空间复杂度** $$ O(N) $$ ** :** 额外创建字符数组,长度为 ` s ` 的长度的 3 倍
44+
45+ #### 代码
46+
47+ {% tabs %}
48+ {% tab title="Python3" %}
49+ ``` go
50+ class Solution :
51+ def replaceSpace (self, s: str) -> str:
52+ ans = []
53+ for v in s:
54+ if v != ' ' : ans.append (v)
55+ else :
56+ ans.append (" % 20" )
57+ return " " .join (ans)
58+ ```
59+ {% endtab %}
60+ {% endtabs %}
61+
62+ ### 思路2 : 原地置换
63+
64+ 由于每次替换从 1 个字符变成 3 个字符,使用字符数组可方便地进行替换。建立字符数组地长度为 s 的长度的 3 倍,这样可保证字符数组可以容纳所有替换后的字符。
65+
66+ ** 算法流程:**
67+
68+ 1 . 获得 s 的长度 length
69+ 2 . 创建字符数组 ans,其长度为 length \* 3
70+ 3 . 初始化 size 为 0,size 表示替换后的字符串的长度
71+ 4 . 从左到右遍历字符串 s
72+ 1 . 获得 s 的当前字符 c
73+ 2 . 如果字符 c 是空格,则令 array\[ size\] = '%',array\[ size + 1\] = '2',array\[ size + 2\] = '0',并将 size 的值加 3
74+ 3 . 如果字符 c 不是空格,则令 array\[ size\] = c,并将 size 的值加 1
75+ 5 . 遍历结束之后,size 的值等于替换后的字符串的长度,从 array 的前 size 个字符创建新字符串,并返回新字符串
76+
77+ ** 复杂度分析:**
78+
79+ * ** 时间复杂度** $$ O(N) $$ ** :** 遍历字符串 ` s ` 一遍。
80+ * ** 空间复杂度** $$ O(N) $$ ** :** 额外创建字符数组,长度为 ` s ` 的长度的 3 倍
81+
82+ #### 代码
83+
84+ {% tabs %}
85+ {% tab title="Go" %}
86+ ``` go
87+ func replaceSpace (s string ) string {
88+ result := make ([]rune, len (s)*3 )
89+
90+ i := 0
91+ for _ , v := range s {
92+ if v != ' ' {
93+ result[i] = v
94+ i++
95+ } else {
96+ result[i] = ' %'
97+ result[i+1 ] = ' 2'
98+ result[i+2 ] = ' 0'
99+ i += 3
100+ }
101+ }
102+ return string (result)[:i]
103+ }
104+ ```
105+ {% endtab %}
106+ {% endtabs %}
107+
108+ ###
109+
110+ ## 总结
111+
112+ 如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[ awesome-golang-algorithm] ( https://github.com/kylesliu/awesome-golang-algorithm )
113+
Original file line number Diff line number Diff line change 6161{% tab title="Go" %}
6262``` go
6363func cuttingRope (n int ) int {
64- dp := make (map [int ]int )
65- dp[1 ] = 1 // 首项
66- for i := 2 ; i < n+1 ; i++ {
67- j , k := 1 , i-1
68- ans := 0
69- for j <= k {
70- ans = max (ans, max (j, dp[j])*max (k, dp[k])) // 递推公式
71- j++
72- k--
73- }
74- dp[i] = ans
75- }
76- return dp[n]
64+ dp := make (map [int ]int )
65+ dp[1 ] = 1 // 首项
66+ for i := 2 ; i < n+1 ; i++ {
67+ j , k := 1 , i-1
68+ ans := 0
69+ for j <= k {
70+ ans = max (ans, max (j, dp[j])*max (k, dp[k])) // 递推公式
71+ j++
72+ k--
73+ }
74+ dp[i] = ans
75+ }
76+ return dp[n]
7777}
7878
7979func max (x int , y int ) int {
80- if x > y {
81- return x
82- }
83- return y
80+ if x > y {
81+ return x
82+ }
83+ return y
8484}
8585```
8686{% endtab %}
You can’t perform that action at this time.
0 commit comments