Add solution 6、8、12

This commit is contained in:
YDZ
2021-03-10 23:35:16 +08:00
parent 1eac64966f
commit a841eac968
32 changed files with 1348 additions and 300 deletions

View File

@ -0,0 +1,26 @@
package leetcode
func convert(s string, numRows int) string {
matrix, down, up := make([][]byte, numRows, numRows), 0, numRows-2
for i := 0; i != len(s); {
if down != numRows {
matrix[down] = append(matrix[down], byte(s[i]))
down++
i++
} else if up > 0 {
matrix[up] = append(matrix[up], byte(s[i]))
up--
i++
} else {
up = numRows - 2
down = 0
}
}
solution := make([]byte, 0, len(s))
for _, row := range matrix {
for _, item := range row {
solution = append(solution, item)
}
}
return string(solution)
}

View File

@ -0,0 +1,53 @@
package leetcode
import (
"fmt"
"testing"
)
type question6 struct {
para6
ans6
}
// para 是参数
// one 代表第一个参数
type para6 struct {
s string
numRows int
}
// ans 是答案
// one 代表第一个答案
type ans6 struct {
one string
}
func Test_Problem6(t *testing.T) {
qs := []question6{
{
para6{"PAYPALISHIRING", 3},
ans6{"PAHNAPLSIIGYIR"},
},
{
para6{"PAYPALISHIRING", 4},
ans6{"PINALSIGYAHRPI"},
},
{
para6{"A", 1},
ans6{"A"},
},
}
fmt.Printf("------------------------Leetcode Problem 6------------------------\n")
for _, q := range qs {
_, p := q.ans6, q.para6
fmt.Printf("【input】:%v 【output】:%v\n", p, convert(p.s, p.numRows))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,107 @@
# [6. ZigZag Conversion](https://leetcode.com/problems/zigzag-conversion/)
## 题目
The string `"PAYPALISHIRING"` is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
```
P A H N
A P L S I I G
Y I R
```
And then read line by line: `"PAHNAPLSIIGYIR"`
Write the code that will take a string and make this conversion given a number of rows:
```
string convert(string s, int numRows);
```
**Example 1:**
```
Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"
```
**Example 2:**
```
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P I N
A L S I G
Y A H R
P I
```
**Example 3:**
```
Input: s = "A", numRows = 1
Output: "A"
```
**Constraints:**
- `1 <= s.length <= 1000`
- `s` consists of English letters (lower-case and upper-case), `','` and `'.'`.
- `1 <= numRows <= 1000`
## 题目大意
将一个给定字符串 `s` 根据给定的行数 `numRows` 以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 `"PAYPALISHIRING"` 行数为 3 时,排列如下:
```go
P A H N
A P L S I I G
Y I R
```
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:`"PAHNAPLSIIGYIR"`
请你实现这个将字符串进行指定行数变换的函数:
```go
string convert(string s, int numRows);
```
## 解题思路
- 这一题没有什么算法思想,考察的是对程序控制的能力。用 2 个变量保存方向当垂直输出的行数达到了规定的目标行数以后需要从下往上转折到第一行循环中控制好方向ji
## 代码
```go
package leetcode
func convert(s string, numRows int) string {
matrix, down, up := make([][]byte, numRows, numRows), 0, numRows-2
for i := 0; i != len(s); {
if down != numRows {
matrix[down] = append(matrix[down], byte(s[i]))
down++
i++
} else if up > 0 {
matrix[up] = append(matrix[up], byte(s[i]))
up--
i++
} else {
up = numRows - 2
down = 0
}
}
solution := make([]byte, 0, len(s))
for _, row := range matrix {
for _, item := range row {
solution = append(solution, item)
}
}
return string(solution)
}
```

View File

@ -0,0 +1,56 @@
package leetcode
func myAtoi(s string) int {
maxInt, signAllowed, whitespaceAllowed, sign, digits := int64(2<<30), true, true, 1, []int{}
for _, c := range s {
if c == ' ' && whitespaceAllowed {
continue
}
if signAllowed {
if c == '+' {
signAllowed = false
whitespaceAllowed = false
continue
} else if c == '-' {
sign = -1
signAllowed = false
whitespaceAllowed = false
continue
}
}
if c < '0' || c > '9' {
break
}
whitespaceAllowed, signAllowed = false, false
digits = append(digits, int(c-48))
}
var num, place int64
place, num = 1, 0
lastLeading0Index := -1
for i, d := range digits {
if d == 0 {
lastLeading0Index = i
} else {
break
}
}
if lastLeading0Index > -1 {
digits = digits[lastLeading0Index+1:]
}
var rtnMax int64
if sign > 0 {
rtnMax = maxInt - 1
} else {
rtnMax = maxInt
}
digitsCount := len(digits)
for i := digitsCount - 1; i >= 0; i-- {
num += int64(digits[i]) * place
place *= 10
if digitsCount-i > 10 || num > rtnMax {
return int(int64(sign) * rtnMax)
}
}
num *= int64(sign)
return int(num)
}

View File

@ -0,0 +1,192 @@
# [8. String to Integer (atoi)](https://leetcode.com/problems/string-to-integer-atoi/)
## 题目
Implement the `myAtoi(string s)` function, which converts a string to a 32-bit signed integer (similar to C/C++'s `atoi` function).
The algorithm for `myAtoi(string s)` is as follows:
1. Read in and ignore any leading whitespace.
2. Check if the next character (if not already at the end of the string) is `'-'` or `'+'`. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present.
3. Read in next the characters until the next non-digit charcter or the end of the input is reached. The rest of the string is ignored.
4. Convert these digits into an integer (i.e. `"123" -> 123`, `"0032" -> 32`). If no digits were read, then the integer is `0`. Change the sign as necessary (from step 2).
5. If the integer is out of the 32-bit signed integer range `[-231, 231 - 1]`, then clamp the integer so that it remains in the range. Specifically, integers less than `231` should be clamped to `231`, and integers greater than `231 - 1` should be clamped to `231 - 1`.
6. Return the integer as the final result.
**Note:**
- Only the space character `' '` is considered a whitespace character.
- **Do not ignore** any characters other than the leading whitespace or the rest of the string after the digits.
**Example 1:**
```
Input: s = "42"
Output: 42
Explanation: The underlined characters are what is read in, the caret is the current reader position.
Step 1: "42" (no characters read because there is no leading whitespace)
^
Step 2: "42" (no characters read because there is neither a '-' nor '+')
^
Step 3: "42" ("42" is read in)
^
The parsed integer is 42.
Since 42 is in the range [-231, 231 - 1], the final result is 42.
```
**Example 2:**
```
Input: s = " -42"
Output: -42
Explanation:
Step 1: " -42" (leading whitespace is read and ignored)
^
Step 2: " -42" ('-' is read, so the result should be negative)
^
Step 3: " -42" ("42" is read in)
^
The parsed integer is -42.
Since -42 is in the range [-231, 231 - 1], the final result is -42.
```
**Example 3:**
```
Input: s = "4193 with words"
Output: 4193
Explanation:
Step 1: "4193 with words" (no characters read because there is no leading whitespace)
^
Step 2: "4193 with words" (no characters read because there is neither a '-' nor '+')
^
Step 3: "4193 with words" ("4193" is read in; reading stops because the next character is a non-digit)
^
The parsed integer is 4193.
Since 4193 is in the range [-231, 231 - 1], the final result is 4193.
```
**Example 4:**
```
Input: s = "words and 987"
Output: 0
Explanation:
Step 1: "words and 987" (no characters read because there is no leading whitespace)
^
Step 2: "words and 987" (no characters read because there is neither a '-' nor '+')
^
Step 3: "words and 987" (reading stops immediately because there is a non-digit 'w')
^
The parsed integer is 0 because no digits were read.
Since 0 is in the range [-231, 231 - 1], the final result is 0.
```
**Example 5:**
```
Input: s = "-91283472332"
Output: -2147483648
Explanation:
Step 1: "-91283472332" (no characters read because there is no leading whitespace)
^
Step 2: "-91283472332" ('-' is read, so the result should be negative)
^
Step 3: "-91283472332" ("91283472332" is read in)
^
The parsed integer is -91283472332.
Since -91283472332 is less than the lower bound of the range [-231, 231 - 1], the final result is clamped to -231 = -2147483648.
```
**Constraints:**
- `0 <= s.length <= 200`
- `s` consists of English letters (lower-case and upper-case), digits (`0-9`), `' '`, `'+'`
## 题目大意
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。
函数 myAtoi(string s) 的算法如下:
- 读入字符串并丢弃无用的前导空格
- 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
- 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
- 将前面步骤读入的这些数字转换为整数(即,"123" -> 123 "0032" -> 32。如果没有读入数字则整数为 0 。必要时更改符号(从步骤 2 开始)。
- 如果整数数超过 32 位有符号整数范围 [231,  231  1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 231 的整数应该被固定为 231 ,大于 231  1 的整数应该被固定为 231  1 。
- 返回整数作为最终结果。
注意:
- 本题中的空白字符只包括空格字符 ' ' 。
- 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。
## 解题思路
- 这题是简单题。题目要求实现类似 `C++``atoi` 函数的功能。这个函数功能是将字符串类型的数字转成 `int` 类型数字。先去除字符串中的前导空格,并判断记录数字的符号。数字需要去掉前导 `0` 。最后将数字转换成数字类型,判断是否超过 `int` 类型的上限 `[-2^31, 2^31 - 1]`,如果超过上限,需要输出边界,即 `-2^31`,或者 `2^31 - 1`
## 代码
```go
package leetcode
func myAtoi(s string) int {
maxInt, signAllowed, whitespaceAllowed, sign, digits := int64(2<<30), true, true, 1, []int{}
for _, c := range s {
if c == ' ' && whitespaceAllowed {
continue
}
if signAllowed {
if c == '+' {
signAllowed = false
whitespaceAllowed = false
continue
} else if c == '-' {
sign = -1
signAllowed = false
whitespaceAllowed = false
continue
}
}
if c < '0' || c > '9' {
break
}
whitespaceAllowed, signAllowed = false, false
digits = append(digits, int(c-48))
}
var num, place int64
place, num = 1, 0
lastLeading0Index := -1
for i, d := range digits {
if d == 0 {
lastLeading0Index = i
} else {
break
}
}
if lastLeading0Index > -1 {
digits = digits[lastLeading0Index+1:]
}
var rtnMax int64
if sign > 0 {
rtnMax = maxInt - 1
} else {
rtnMax = maxInt
}
digitsCount := len(digits)
for i := digitsCount - 1; i >= 0; i-- {
num += int64(digits[i]) * place
place *= 10
if digitsCount-i > 10 || num > rtnMax {
return int(int64(sign) * rtnMax)
}
}
num *= int64(sign)
return int(num)
}
```

View File

@ -0,0 +1,15 @@
package leetcode
func intToRoman(num int) string {
values := []int{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}
symbols := []string{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}
res, i := "", 0
for num != 0 {
for values[i] > num {
i++
}
num -= values[i]
res += symbols[i]
}
return res
}

View File

@ -0,0 +1,71 @@
package leetcode
import (
"fmt"
"testing"
)
type question12 struct {
para12
ans12
}
// para 是参数
// one 代表第一个参数
type para12 struct {
one int
}
// ans 是答案
// one 代表第一个答案
type ans12 struct {
one string
}
func Test_Problem12(t *testing.T) {
qs := []question12{
{
para12{3},
ans12{"III"},
},
{
para12{4},
ans12{"IV"},
},
{
para12{9},
ans12{"IX"},
},
{
para12{58},
ans12{"LVIII"},
},
{
para12{1994},
ans12{"MCMXCIV"},
},
{
para12{123},
ans12{"CXXIII"},
},
{
para12{120},
ans12{"CXX"},
},
}
fmt.Printf("------------------------Leetcode Problem 12------------------------\n")
for _, q := range qs {
_, p := q.ans12, q.para12
fmt.Printf("【input】:%v 【output】:%v\n", p.one, intToRoman(p.one))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,102 @@
# [12. Integer to Roman](https://leetcode.com/problems/integer-to-roman/)
## 题目
Roman numerals are represented by seven different symbols: `I`, `V`, `X`, `L`, `C`, `D` and `M`.
```
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
```
For example, `2` is written as `II` in Roman numeral, just two one's added together. `12` is written as `XII`, which is simply `X + II`. The number `27` is written as `XXVII`, which is `XX + V + II`.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not `IIII`. Instead, the number four is written as `IV`. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as `IX`. There are six instances where subtraction is used:
- `I` can be placed before `V` (5) and `X` (10) to make 4 and 9.
- `X` can be placed before `L` (50) and `C` (100) to make 40 and 90.
- `C` can be placed before `D` (500) and `M` (1000) to make 400 and 900.
Given an integer, convert it to a roman numeral.
**Example 1:**
```
Input: num = 3
Output: "III"
```
**Example 2:**
```
Input: num = 4
Output: "IV"
```
**Example 3:**
```
Input: num = 9
Output: "IX"
```
**Example 4:**
```
Input: num = 58
Output: "LVIII"
Explanation: L = 50, V = 5, III = 3.
```
**Example 5:**
```
Input: num = 1994
Output: "MCMXCIV"
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
```
**Constraints:**
- `1 <= num <= 3999`
## 题目大意
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况
- I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
- X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
- C 可以放在 D (500) 和 M (1000) 的左边来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
## 解题思路
- 依照题意,优先选择大的数字,解题思路采用贪心算法。将 1-3999 范围内的罗马数字从大到小放在数组中,从头选择到尾,即可把整数转成罗马数字。
## 代码
```go
package leetcode
func intToRoman(num int) string {
values := []int{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}
symbols := []string{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}
res, i := "", 0
for num != 0 {
for values[i] > num {
i++
}
num -= values[i]
res += symbols[i]
}
return res
}
```