Add solution 228、1694、1695

This commit is contained in:
YDZ
2021-01-12 11:04:25 +08:00
parent 1bc9d34209
commit fbbc4ff73a
16 changed files with 1618 additions and 828 deletions

View File

@ -0,0 +1,19 @@
package leetcode
import (
"strconv"
)
func summaryRanges(nums []int) (ans []string) {
for i, n := 0, len(nums); i < n; {
left := i
for i++; i < n && nums[i-1]+1 == nums[i]; i++ {
}
s := strconv.Itoa(nums[left])
if left != i-1 {
s += "->" + strconv.Itoa(nums[i-1])
}
ans = append(ans, s)
}
return
}

View File

@ -0,0 +1,62 @@
package leetcode
import (
"fmt"
"testing"
)
type question228 struct {
para228
ans228
}
// para 是参数
// one 代表第一个参数
type para228 struct {
nums []int
}
// ans 是答案
// one 代表第一个答案
type ans228 struct {
ans []string
}
func Test_Problem228(t *testing.T) {
qs := []question228{
{
para228{[]int{0, 1, 2, 4, 5, 7}},
ans228{[]string{"0->2", "4->5", "7"}},
},
{
para228{[]int{0, 2, 3, 4, 6, 8, 9}},
ans228{[]string{"0", "2->4", "6", "8->9"}},
},
{
para228{[]int{}},
ans228{[]string{}},
},
{
para228{[]int{-1}},
ans228{[]string{"-1"}},
},
{
para228{[]int{0}},
ans228{[]string{"0"}},
},
}
fmt.Printf("------------------------Leetcode Problem 228------------------------\n")
for _, q := range qs {
_, p := q.ans228, q.para228
fmt.Printf("【input】:%v 【output】:%v\n", p, summaryRanges(p.nums))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,107 @@
# [228. Summary Ranges](https://leetcode.com/problems/summary-ranges/)
## 题目
You are given a **sorted unique** integer array `nums`.
Return *the **smallest sorted** list of ranges that **cover all the numbers in the array exactly***. That is, each element of `nums` is covered by exactly one of the ranges, and there is no integer `x` such that `x` is in one of the ranges but not in `nums`.
Each range `[a,b]` in the list should be output as:
- `"a->b"` if `a != b`
- `"a"` if `a == b`
**Example 1:**
```
Input: nums = [0,1,2,4,5,7]
Output: ["0->2","4->5","7"]
Explanation: The ranges are:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"
```
**Example 2:**
```
Input: nums = [0,2,3,4,6,8,9]
Output: ["0","2->4","6","8->9"]
Explanation: The ranges are:
[0,0] --> "0"
[2,4] --> "2->4"
[6,6] --> "6"
[8,9] --> "8->9"
```
**Example 3:**
```
Input: nums = []
Output: []
```
**Example 4:**
```
Input: nums = [-1]
Output: ["-1"]
```
**Example 5:**
```
Input: nums = [0]
Output: ["0"]
```
**Constraints:**
- `0 <= nums.length <= 20`
- `231 <= nums[i] <= 231 - 1`
- All the values of `nums` are **unique**.
- `nums` is sorted in ascending order.
## 题目大意
给定一个无重复元素的有序整数数组 nums 。
返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表。也就是说nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。
列表中的每个区间范围 [a,b] 应该按如下格式输出:
- "a->b" ,如果 a != b
- "a" ,如果 a == b
## 解题思路
- 简单题。按照题意,用一个游标变量累加寻找连续的区间。一旦出现了中断,就按照题意格式输出。输出的规则有多种,带箭头的区间,单个元素区间,空区间。
## 代码
```go
package leetcode
import (
"strconv"
)
func summaryRanges(nums []int) (ans []string) {
for i, n := 0, len(nums); i < n; {
left := i
for i++; i < n && nums[i-1]+1 == nums[i]; i++ {
}
s := strconv.Itoa(nums[left])
if left != i-1 {
s += "->" + strconv.Itoa(nums[i-1])
}
ans = append(ans, s)
}
return
}
```

View File

@ -0,0 +1,37 @@
package leetcode
import (
"strings"
)
func reformatNumber(number string) string {
parts, nums := []string{}, []rune{}
for _, r := range number {
if r != '-' && r != ' ' {
nums = append(nums, r)
}
}
threeDigits, twoDigits := len(nums)/3, 0
switch len(nums) % 3 {
case 1:
threeDigits--
twoDigits = 2
case 2:
twoDigits = 1
default:
twoDigits = 0
}
for i := 0; i < threeDigits; i++ {
s := ""
s += string(nums[0:3])
nums = nums[3:]
parts = append(parts, s)
}
for i := 0; i < twoDigits; i++ {
s := ""
s += string(nums[0:2])
nums = nums[2:]
parts = append(parts, s)
}
return strings.Join(parts, "-")
}

View File

@ -0,0 +1,67 @@
package leetcode
import (
"fmt"
"testing"
)
type question1694 struct {
para1694
ans1694
}
// para 是参数
// one 代表第一个参数
type para1694 struct {
number string
}
// ans 是答案
// one 代表第一个答案
type ans1694 struct {
one string
}
func Test_Problem1694(t *testing.T) {
qs := []question1694{
{
para1694{"1-23-45 6"},
ans1694{"123-456"},
},
{
para1694{"123 4-567"},
ans1694{"123-45-67"},
},
{
para1694{"123 4-5678"},
ans1694{"123-456-78"},
},
{
para1694{"12"},
ans1694{"12"},
},
{
para1694{"--17-5 229 35-39475 "},
ans1694{"175-229-353-94-75"},
},
{
para1694{"9964-"},
ans1694{"99-64"},
},
}
fmt.Printf("------------------------Leetcode Problem 1694------------------------\n")
for _, q := range qs {
_, p := q.ans1694, q.para1694
fmt.Printf("【input】:%v 【output】:%v\n", p, reformatNumber(p.number))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,135 @@
# [1694. Reformat Phone Number](https://leetcode.com/problems/reformat-phone-number/)
## 题目
You are given a phone number as a string `number`. `number` consists of digits, spaces `' '`, and/or dashes `'-'`.
You would like to reformat the phone number in a certain manner. Firstly, **remove** all spaces and dashes. Then, **group** the digits from left to right into blocks of length 3 **until** there are 4 or fewer digits. The final digits are then grouped as follows:
- 2 digits: A single block of length 2.
- 3 digits: A single block of length 3.
- 4 digits: Two blocks of length 2 each.
The blocks are then joined by dashes. Notice that the reformatting process should **never** produce any blocks of length 1 and produce **at most** two blocks of length 2.
Return *the phone number after formatting.*
**Example 1:**
```
Input: number = "1-23-45 6"
Output: "123-456"
Explanation: The digits are "123456".
Step 1: There are more than 4 digits, so group the next 3 digits. The 1st block is "123".
Step 2: There are 3 digits remaining, so put them in a single block of length 3. The 2nd block is "456".
Joining the blocks gives "123-456".
```
**Example 2:**
```
Input: number = "123 4-567"
Output: "123-45-67"
Explanation: The digits are "1234567".
Step 1: There are more than 4 digits, so group the next 3 digits. The 1st block is "123".
Step 2: There are 4 digits left, so split them into two blocks of length 2. The blocks are "45" and "67".
Joining the blocks gives "123-45-67".
```
**Example 3:**
```
Input: number = "123 4-5678"
Output: "123-456-78"
Explanation: The digits are "12345678".
Step 1: The 1st block is "123".
Step 2: The 2nd block is "456".
Step 3: There are 2 digits left, so put them in a single block of length 2. The 3rd block is "78".
Joining the blocks gives "123-456-78".
```
**Example 4:**
```
Input: number = "12"
Output: "12"
```
**Example 5:**
```
Input: number = "--17-5 229 35-39475 "
Output: "175-229-353-94-75"
```
**Constraints:**
- `2 <= number.length <= 100`
- `number` consists of digits and the characters `'-'` and `' '`.
- There are at least **two** digits in `number`.
## 题目大意
给你一个字符串形式的电话号码 number 。number 由数字、空格 ' '、和破折号 '-' 组成。
请你按下述方式重新格式化电话号码。
- 首先,删除 所有的空格和破折号。
- 其次,将数组从左到右 每 3 个一组 分块,直到 剩下 4 个或更少数字。剩下的数字将按下述规定再分块:
- 2 个数字:单个含 2 个数字的块。
- 3 个数字:单个含 3 个数字的块。
- 4 个数字:两个分别含 2 个数字的块。
最后用破折号将这些块连接起来。注意,重新格式化过程中 不应该 生成仅含 1 个数字的块,并且 最多 生成两个含 2 个数字的块。返回格式化后的电话号码。
## 解题思路
- 简单题。先判断号码是不是 2 位和 4 位,如果是,单独输出这 2 种情况。剩下的都是 3 位以上了,取余,判断剩余的数字是 2 个还是 4 个。这时不可能存在剩 1 位数的情况。除 3 余 1即剩 4 位的情况,末尾 4 位需要 2 个一组输出。除 3 余 2即剩 2 位的情况。处理好末尾,再逆序每 3 个一组连接 "-" 即可。可能需要注意的 case 见 test 文件。
## 代码
```go
package leetcode
import (
"strings"
)
func reformatNumber(number string) string {
parts, nums := []string{}, []rune{}
for _, r := range number {
if r != '-' && r != ' ' {
nums = append(nums, r)
}
}
threeDigits, twoDigits := len(nums)/3, 0
switch len(nums) % 3 {
case 1:
threeDigits--
twoDigits = 2
case 2:
twoDigits = 1
default:
twoDigits = 0
}
for i := 0; i < threeDigits; i++ {
s := ""
s += string(nums[0:3])
nums = nums[3:]
parts = append(parts, s)
}
for i := 0; i < twoDigits; i++ {
s := ""
s += string(nums[0:2])
nums = nums[2:]
parts = append(parts, s)
}
return strings.Join(parts, "-")
}
```

View File

@ -0,0 +1,30 @@
package leetcode
func maximumUniqueSubarray(nums []int) int {
if len(nums) == 0 {
return 0
}
result, left, right, freq := 0, 0, -1, map[int]int{}
for left < len(nums) {
if right+1 < len(nums) && freq[nums[right+1]] == 0 {
freq[nums[right+1]]++
right++
} else {
freq[nums[left]]--
left++
}
sum := 0
for i := left; i <= right; i++ {
sum += nums[i]
}
result = max(result, sum)
}
return result
}
func max(a int, b int) int {
if a > b {
return a
}
return b
}

View File

@ -0,0 +1,47 @@
package leetcode
import (
"fmt"
"testing"
)
type question1695 struct {
para1695
ans1695
}
// para 是参数
// one 代表第一个参数
type para1695 struct {
nums []int
}
// ans 是答案
// one 代表第一个答案
type ans1695 struct {
one int
}
func Test_Problem1695(t *testing.T) {
qs := []question1695{
{
para1695{[]int{4, 2, 4, 5, 6}},
ans1695{17},
},
{
para1695{[]int{5, 2, 1, 2, 5, 2, 1, 2, 5}},
ans1695{8},
},
}
fmt.Printf("------------------------Leetcode Problem 1695------------------------\n")
for _, q := range qs {
_, p := q.ans1695, q.para1695
fmt.Printf("【input】:%v 【output】:%v\n", p, maximumUniqueSubarray(p.nums))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,74 @@
# [1695. Maximum Erasure Value](https://leetcode.com/problems/maximum-erasure-value/)
## 题目
You are given an array of positive integers `nums` and want to erase a subarray containing **unique elements**. The **score** you get by erasing the subarray is equal to the **sum** of its elements.
Return *the **maximum score** you can get by erasing **exactly one** subarray.*
An array `b` is called to be a subarray of `a` if it forms a contiguous subsequence of `a`, that is, if it is equal to `a[l],a[l+1],...,a[r]` for some `(l,r)`.
**Example 1:**
```
Input: nums = [4,2,4,5,6]
Output: 17
Explanation: The optimal subarray here is [2,4,5,6].
```
**Example 2:**
```
Input: nums = [5,2,1,2,5,2,1,2,5]
Output: 8
Explanation: The optimal subarray here is [5,2,1] or [1,2,5].
```
**Constraints:**
- `1 <= nums.length <= 105`
- `1 <= nums[i] <= 104`
## 题目大意
给你一个正整数数组 nums ,请你从中删除一个含有 若干不同元素 的子数组。删除子数组的 得分 就是子数组各元素之 和 。返回 只删除一个 子数组可获得的 最大得分 。如果数组 b 是数组 a 的一个连续子序列,即如果它等于 a[l],a[l+1],...,a[r] 那么它就是 a 的一个子数组。
## 解题思路
- 读完题立马能识别出这是经典的滑动窗口题。利用滑动窗口从左往右滑动窗口,滑动过程中统计频次,如果是不同元素,右边界窗口又移,否则左边窗口缩小。每次移动更新 max 值。最终扫完一遍以后max 值即为所求。
## 代码
```go
package leetcode
func maximumUniqueSubarray(nums []int) int {
if len(nums) == 0 {
return 0
}
result, left, right, freq := 0, 0, -1, map[int]int{}
for left < len(nums) {
if right+1 < len(nums) && freq[nums[right+1]] == 0 {
freq[nums[right+1]]++
right++
} else {
freq[nums[left]]--
left++
}
sum := 0
for i := left; i <= right; i++ {
sum += nums[i]
}
result = max(result, sum)
}
return result
}
func max(a int, b int) int {
if a > b {
return a
}
return b
}
```

View File

@ -1,51 +0,0 @@
package leetcode
func reformatNumber(number string) string {
str, count := "", 0
for i := 0; i < len(number); i++ {
if number[i] != '-' && number[i] != ' ' {
str += string(number[i])
// str = append(str, number[i])
}
}
if len(str) == 4 {
str = str[:2] + "-" + str[2:]
return str
}
if len(str) > 3 {
if (len(str)-4)%3 == 0 {
for i := len(str) - 5; i >= 0; i-- {
count++
if count%3 == 0 && i != 0 {
str = str[:i] + "-" + str[i:]
}
}
str = str[:len(str)-2] + "-" + str[len(str)-2:]
str = str[:len(str)-5] + "-" + str[len(str)-5:]
return str
}
if (len(str)-2)%3 == 0 {
for i := len(str) - 3; i >= 0; i-- {
count++
if count%3 == 0 && i != 0 {
str = str[:i] + "-" + str[i:]
}
}
str = str[:len(str)-2] + "-" + str[len(str)-2:]
return str
}
length := len(str)
count = 0
for j := 0; j < len(str); j++ {
count++
if count%3 == 0 && count != length {
// head :=
// tail :=
str = str[:j+1] + "-" + str[j+1:]
j++
}
}
}
return str
}

View File

@ -1,67 +0,0 @@
package leetcode
import (
"fmt"
"testing"
)
type question1690 struct {
para1690
ans1690
}
// para 是参数
// one 代表第一个参数
type para1690 struct {
number string
}
// ans 是答案
// one 代表第一个答案
type ans1690 struct {
one string
}
func Test_Problem1690(t *testing.T) {
qs := []question1690{
{
para1690{"1-23-45 6"},
ans1690{"123-456"},
},
{
para1690{"123 4-567"},
ans1690{"123-45-67"},
},
{
para1690{"123 4-5678"},
ans1690{"123-456-78"},
},
{
para1690{"12"},
ans1690{"12"},
},
{
para1690{"--17-5 229 35-39475 "},
ans1690{"175-229-353-94-75"},
},
{
para1690{"9964-"},
ans1690{"99-64"},
},
}
fmt.Printf("------------------------Leetcode Problem 1690------------------------\n")
for _, q := range qs {
_, p := q.ans1690, q.para1690
fmt.Printf("【input】:%v 【output】:%v\n", p, reformatNumber(p.number))
}
fmt.Printf("\n\n\n")
}