Add solution 43、45、73、227

This commit is contained in:
YDZ
2021-03-11 03:01:13 +08:00
parent a841eac968
commit 8bb84f2edc
41 changed files with 1421 additions and 354 deletions

View File

@ -0,0 +1,62 @@
package leetcode
import (
"fmt"
"testing"
)
type question8 struct {
para8
ans8
}
// para 是参数
// one 代表第一个参数
type para8 struct {
one string
}
// ans 是答案
// one 代表第一个答案
type ans8 struct {
one int
}
func Test_Problem8(t *testing.T) {
qs := []question8{
{
para8{"42"},
ans8{42},
},
{
para8{" -42"},
ans8{-42},
},
{
para8{"4193 with words"},
ans8{4193},
},
{
para8{"words and 987"},
ans8{0},
},
{
para8{"-91283472332"},
ans8{-2147483648},
},
}
fmt.Printf("------------------------Leetcode Problem 8------------------------\n")
for _, q := range qs {
_, p := q.ans8, q.para8
fmt.Printf("【input】:%v 【output】:%v\n", p.one, myAtoi(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,25 @@
package leetcode
func multiply(num1 string, num2 string) string {
if num1 == "0" || num2 == "0" {
return "0"
}
b1, b2, tmp := []byte(num1), []byte(num2), make([]int, len(num1)+len(num2))
for i := 0; i < len(b1); i++ {
for j := 0; j < len(b2); j++ {
tmp[i+j+1] += int(b1[i]-'0') * int(b2[j]-'0')
}
}
for i := len(tmp) - 1; i > 0; i-- {
tmp[i-1] += tmp[i] / 10
tmp[i] = tmp[i] % 10
}
if tmp[0] == 0 {
tmp = tmp[1:]
}
res := make([]byte, len(tmp))
for i := 0; i < len(tmp); i++ {
res[i] = '0' + byte(tmp[i])
}
return string(res)
}

View File

@ -0,0 +1,48 @@
package leetcode
import (
"fmt"
"testing"
)
type question43 struct {
para43
ans43
}
// para 是参数
// one 代表第一个参数
type para43 struct {
num1 string
num2 string
}
// ans 是答案
// one 代表第一个答案
type ans43 struct {
one string
}
func Test_Problem43(t *testing.T) {
qs := []question43{
{
para43{"2", "3"},
ans43{"6"},
},
{
para43{"123", "456"},
ans43{"56088"},
},
}
fmt.Printf("------------------------Leetcode Problem 43------------------------\n")
for _, q := range qs {
_, p := q.ans43, q.para43
fmt.Printf("【input】:%v 【output】:%v\n", p, multiply(p.num1, p.num2))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,66 @@
# [43. Multiply Strings](https://leetcode.com/problems/multiply-strings/)
## 题目
Given two non-negative integers `num1` and `num2` represented as strings, return the product of `num1` and `num2`, also represented as a string.
**Note:** You must not use any built-in BigInteger library or convert the inputs to integer directly.
**Example 1:**
```
Input: num1 = "2", num2 = "3"
Output: "6"
```
**Example 2:**
```
Input: num1 = "123", num2 = "456"
Output: "56088"
```
**Constraints:**
- `1 <= num1.length, num2.length <= 200`
- `num1` and `num2` consist of digits only.
- Both `num1` and `num2` do not contain any leading zero, except the number `0` itself.
## 题目大意
给定两个以字符串形式表示的非负整数 num1 和 num2返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
## 解题思路
- 用数组模拟乘法。创建一个数组长度为 `len(num1) + len(num2)` 的数组用于存储乘积。对于任意 `0 ≤ i < len(num1)``0 ≤ j < len(num2)``num1[i] * num2[j]` 的结果位于 `tmp[i+j+1]`,如果 `tmp[i+j+1]≥10`,则将进位部分加到 `tmp[i+j]`。最后,将数组 `tmp` 转成字符串,如果最高位是 0 则舍弃最高位。
## 代码
```go
package leetcode
func multiply(num1 string, num2 string) string {
if num1 == "0" || num2 == "0" {
return "0"
}
b1, b2, tmp := []byte(num1), []byte(num2), make([]int, len(num1)+len(num2))
for i := 0; i < len(b1); i++ {
for j := 0; j < len(b2); j++ {
tmp[i+j+1] += int(b1[i]-'0') * int(b2[j]-'0')
}
}
for i := len(tmp) - 1; i > 0; i-- {
tmp[i-1] += tmp[i] / 10
tmp[i] = tmp[i] % 10
}
if tmp[0] == 0 {
tmp = tmp[1:]
}
res := make([]byte, len(tmp))
for i := 0; i < len(tmp); i++ {
res[i] = '0' + byte(tmp[i])
}
return string(res)
}
```

View File

@ -0,0 +1,21 @@
package leetcode
func jump(nums []int) int {
if len(nums) == 1 {
return 0
}
needChoose, canReach, step := 0, 0, 0
for i, x := range nums {
if i+x > canReach {
canReach = i + x
if canReach >= len(nums)-1 {
return step + 1
}
}
if i == needChoose {
needChoose = canReach
step++
}
}
return step
}

View File

@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question45 struct {
para45
ans45
}
// para 是参数
// one 代表第一个参数
type para45 struct {
nums []int
}
// ans 是答案
// one 代表第一个答案
type ans45 struct {
one int
}
func Test_Problem45(t *testing.T) {
qs := []question45{
{
para45{[]int{2, 3, 1, 1, 4}},
ans45{2},
},
{
para45{[]int{2, 3, 0, 1, 4}},
ans45{2},
},
}
fmt.Printf("------------------------Leetcode Problem 45------------------------\n")
for _, q := range qs {
_, p := q.ans45, q.para45
fmt.Printf("【input】:%v 【output】:%v\n", p, jump(p.nums))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,67 @@
# [45. Jump Game II](https://leetcode.com/problems/jump-game-ii/)
## 题目
Given an array of non-negative integers `nums`, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
You can assume that you can always reach the last index.
**Example 1:**
```
Input: nums = [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index.
```
**Example 2:**
```
Input: nums = [2,3,0,1,4]
Output: 2
```
**Constraints:**
- `1 <= nums.length <= 1000`
- `0 <= nums[i] <= 10^5`
## 题目大意
给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。你的目标是使用最少的跳跃次数到达数组的最后一个位置。
## 解题思路
- 要求找到最少跳跃次数,顺理成章的会想到用贪心算法解题。扫描步数数组,维护当前能够到达最大下标的位置,记为能到达的最远边界,如果扫描过程中到达了最远边界,更新边界并将跳跃次数 + 1。
- 扫描数组的时候,其实不需要扫描最后一个元素,因为在跳到最后一个元素之前,能到达的最远边界一定大于等于最后一个元素的位置,不然就跳不到最后一个元素,到达不了终点了;如果遍历到最后一个元素,说明边界正好为最后一个位置,最终跳跃次数直接 + 1 即可,也不需要访问最后一个元素。
## 代码
```go
package leetcode
func jump(nums []int) int {
if len(nums) == 1 {
return 0
}
needChoose, canReach, step := 0, 0, 0
for i, x := range nums {
if i+x > canReach {
canReach = i + x
if canReach >= len(nums)-1 {
return step + 1
}
}
if i == needChoose {
needChoose = canReach
step++
}
}
return step
}
```

View File

@ -0,0 +1,54 @@
package leetcode
func setZeroes(matrix [][]int) {
if len(matrix) == 0 || len(matrix[0]) == 0 {
return
}
isFirstRowExistZero, isFirstColExistZero := false, false
for i := 0; i < len(matrix); i++ {
if matrix[i][0] == 0 {
isFirstColExistZero = true
break
}
}
for j := 0; j < len(matrix[0]); j++ {
if matrix[0][j] == 0 {
isFirstRowExistZero = true
break
}
}
for i := 1; i < len(matrix); i++ {
for j := 1; j < len(matrix[0]); j++ {
if matrix[i][j] == 0 {
matrix[i][0] = 0
matrix[0][j] = 0
}
}
}
// 处理[1:]行全部置 0
for i := 1; i < len(matrix); i++ {
if matrix[i][0] == 0 {
for j := 1; j < len(matrix[0]); j++ {
matrix[i][j] = 0
}
}
}
// 处理[1:]列全部置 0
for j := 1; j < len(matrix[0]); j++ {
if matrix[0][j] == 0 {
for i := 1; i < len(matrix); i++ {
matrix[i][j] = 0
}
}
}
if isFirstRowExistZero {
for j := 0; j < len(matrix[0]); j++ {
matrix[0][j] = 0
}
}
if isFirstColExistZero {
for i := 0; i < len(matrix); i++ {
matrix[i][0] = 0
}
}
}

View File

@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question73 struct {
para73
ans73
}
// para 是参数
// one 代表第一个参数
type para73 struct {
matrix [][]int
}
// ans 是答案
// one 代表第一个答案
type ans73 struct {
}
func Test_Problem73(t *testing.T) {
qs := []question73{
{
para73{[][]int{
{0, 1, 2, 0},
{3, 4, 5, 2},
{1, 3, 1, 5},
}},
ans73{},
},
}
fmt.Printf("------------------------Leetcode Problem 73------------------------\n")
for _, q := range qs {
_, p := q.ans73, q.para73
fmt.Printf("【input】:%v ", p)
setZeroes(p.matrix)
fmt.Printf("【output】:%v\n", p)
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,104 @@
# [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/)
## 题目
Given an *`m* x *n*` matrix. If an element is **0**, set its entire row and column to **0**. Do it **[in-place](https://en.wikipedia.org/wiki/In-place_algorithm)**.
**Follow up:**
- A straight forward solution using O(*mn*) space is probably a bad idea.
- A simple improvement uses O(*m* + *n*) space, but still not the best solution.
- Could you devise a constant space solution?
**Example 1:**
![https://assets.leetcode.com/uploads/2020/08/17/mat1.jpg](https://assets.leetcode.com/uploads/2020/08/17/mat1.jpg)
```
Input: matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]
```
**Example 2:**
![https://assets.leetcode.com/uploads/2020/08/17/mat2.jpg](https://assets.leetcode.com/uploads/2020/08/17/mat2.jpg)
```
Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]
```
**Constraints:**
- `m == matrix.length`
- `n == matrix[0].length`
- `1 <= m, n <= 200`
- `2^31 <= matrix[i][j] <= 2^31 - 1`
## 题目大意
给定一个 `m x n` 的矩阵,如果一个元素为 0则将其所在行和列的所有元素都设为 0。请使用原地算法。
## 解题思路
- 此题考查对程序的控制能力,无算法思想。题目要求采用原地的算法,所有修改即在原二维数组上进行。在二维数组中有 2 个特殊位置,一个是第一行,一个是第一列。它们的特殊性在于,它们之间只要有一个 0它们都会变为全 0 。先用 2 个变量记录这一行和这一列中是否有 0防止之后的修改覆盖了这 2 个地方。然后除去这一行和这一列以外的部分判断是否有 0如果有 0将它们所在的行第一个元素标记为 0所在列的第一个元素标记为 0 。最后通过标记,将对应的行列置 0 即可。
## 代码
```go
package leetcode
func setZeroes(matrix [][]int) {
if len(matrix) == 0 || len(matrix[0]) == 0 {
return
}
isFirstRowExistZero, isFirstColExistZero := false, false
for i := 0; i < len(matrix); i++ {
if matrix[i][0] == 0 {
isFirstColExistZero = true
break
}
}
for j := 0; j < len(matrix[0]); j++ {
if matrix[0][j] == 0 {
isFirstRowExistZero = true
break
}
}
for i := 1; i < len(matrix); i++ {
for j := 1; j < len(matrix[0]); j++ {
if matrix[i][j] == 0 {
matrix[i][0] = 0
matrix[0][j] = 0
}
}
}
// 处理[1:]行全部置 0
for i := 1; i < len(matrix); i++ {
if matrix[i][0] == 0 {
for j := 1; j < len(matrix[0]); j++ {
matrix[i][j] = 0
}
}
}
// 处理[1:]列全部置 0
for j := 1; j < len(matrix[0]); j++ {
if matrix[0][j] == 0 {
for i := 1; i < len(matrix); i++ {
matrix[i][j] = 0
}
}
}
if isFirstRowExistZero {
for j := 0; j < len(matrix[0]); j++ {
matrix[0][j] = 0
}
}
if isFirstColExistZero {
for i := 0; i < len(matrix); i++ {
matrix[i][0] = 0
}
}
}
```

View File

@ -0,0 +1,29 @@
package leetcode
func calculate(s string) int {
stack, preSign, num, res := []int{}, '+', 0, 0
for i, ch := range s {
isDigit := '0' <= ch && ch <= '9'
if isDigit {
num = num*10 + int(ch-'0')
}
if !isDigit && ch != ' ' || i == len(s)-1 {
switch preSign {
case '+':
stack = append(stack, num)
case '-':
stack = append(stack, -num)
case '*':
stack[len(stack)-1] *= num
default:
stack[len(stack)-1] /= num
}
preSign = ch
num = 0
}
}
for _, v := range stack {
res += v
}
return res
}

View File

@ -0,0 +1,66 @@
package leetcode
import (
"fmt"
"testing"
)
type question227 struct {
para227
ans227
}
// para 是参数
// one 代表第一个参数
type para227 struct {
one string
}
// ans 是答案
// one 代表第一个答案
type ans227 struct {
one int
}
func Test_Problem227(t *testing.T) {
qs := []question227{
{
para227{"3+2*2"},
ans227{7},
},
{
para227{"3/2"},
ans227{1},
},
{
para227{" 3+5 / 2 "},
ans227{5},
},
{
para227{"1 + 1"},
ans227{2},
},
{
para227{" 2-1 + 2 "},
ans227{3},
},
{
para227{"2-5/6"},
ans227{2},
},
}
fmt.Printf("------------------------Leetcode Problem 227------------------------\n")
for _, q := range qs {
_, p := q.ans227, q.para227
fmt.Printf("【input】:%v 【output】:%v\n", p, calculate(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,80 @@
# [227. Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/)
## 题目
Given a string `s` which represents an expression, *evaluate this expression and return its value*.
The integer division should truncate toward zero.
**Example 1:**
```
Input: s = "3+2*2"
Output: 7
```
**Example 2:**
```
Input: s = " 3/2 "
Output: 1
```
**Example 3:**
```
Input: s = " 3+5 / 2 "
Output: 5
```
**Constraints:**
- `1 <= s.length <= 3 * 10^5`
- `s` consists of integers and operators `('+', '-', '*', '/')` separated by some number of spaces.
- `s` represents **a valid expression**.
- All the integers in the expression are non-negative integers in the range `[0, 2^31 - 1]`.
- The answer is **guaranteed** to fit in a **32-bit integer**.
## 题目大意
给你一个字符串表达式 `s` ,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。
## 解题思路
- 这道题是第 224 题的加强版。第 224 题中只有加减运算和括号,这一题增加了乘除运算。由于乘除运算的优先级高于加减。所以先计算乘除运算,将算出来的结果再替换回原来的算式中。最后只剩下加减运算,于是题目降级成了第 224 题。
- 把加减运算符号后面的数字压入栈中,遇到乘除运算,直接将它与栈顶的元素计算,并将计算后的结果放入栈顶。若读到一个运算符,或者遍历到字符串末尾,即认为是遍历到了数字末尾。处理完该数字后,更新 `preSign` 为当前遍历的字符。遍历完字符串 `s` 后,将栈中元素累加,即为该字符串表达式的值。时间复杂度 O(n),空间复杂度 O(n)。
## 代码
```go
package leetcode
func calculate(s string) int {
stack, preSign, num, res := []int{}, '+', 0, 0
for i, ch := range s {
isDigit := '0' <= ch && ch <= '9'
if isDigit {
num = num*10 + int(ch-'0')
}
if !isDigit && ch != ' ' || i == len(s)-1 {
switch preSign {
case '+':
stack = append(stack, num)
case '-':
stack = append(stack, -num)
case '*':
stack[len(stack)-1] *= num
default:
stack[len(stack)-1] /= num
}
preSign = ch
num = 0
}
}
for _, v := range stack {
res += v
}
return res
}
```