Add solution 0667

This commit is contained in:
YDZ
2021-04-13 13:09:06 +08:00
parent a8f9bfb98c
commit 8ded561341
26 changed files with 641 additions and 445 deletions

View File

@ -0,0 +1,16 @@
package leetcode
func constructArray(n int, k int) []int {
res := []int{}
for i := 0; i < n-k-1; i++ {
res = append(res, i+1)
}
for i := n - k; i < n-k+(k+1)/2; i++ {
res = append(res, i)
res = append(res, 2*n-k-i)
}
if k%2 == 0 {
res = append(res, n-k+(k+1)/2)
}
return res
}

View File

@ -0,0 +1,48 @@
package leetcode
import (
"fmt"
"testing"
)
type question667 struct {
para667
ans667
}
// para 是参数
// one 代表第一个参数
type para667 struct {
n int
k int
}
// ans 是答案
// one 代表第一个答案
type ans667 struct {
one []int
}
func Test_Problem667(t *testing.T) {
qs := []question667{
{
para667{3, 1},
ans667{[]int{1, 2, 3}},
},
{
para667{3, 2},
ans667{[]int{1, 3, 2}},
},
}
fmt.Printf("------------------------Leetcode Problem 667------------------------\n")
for _, q := range qs {
_, p := q.ans667, q.para667
fmt.Printf("【input】:%v 【output】:%v\n", p, constructArray(p.n, p.k))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,62 @@
# [667. Beautiful Arrangement II](https://leetcode.com/problems/beautiful-arrangement-ii/)
## 题目
Given two integers `n` and `k`, you need to construct a list which contains `n` different positive integers ranging from `1` to `n` and obeys the following requirement:Suppose this list is [a1, a2, a3, ... , an], then the list [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] has exactly `k` distinct integers.
If there are multiple answers, print any of them.
**Example 1:**
```
Input: n = 3, k = 1
Output: [1, 2, 3]
Explanation: The [1, 2, 3] has three different positive integers ranging from 1 to 3, and the [1, 1] has exactly 1 distinct integer: 1.
```
**Example 2:**
```
Input: n = 3, k = 2
Output: [1, 3, 2]
Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.
```
**Note:**
1. The `n` and `k` are in the range 1 <= k < n <= 10^4.
## 题目大意
给定两个整数 n  k你需要实现一个数组这个数组包含从 1  n  n 个不同整数同时满足以下条件
- 如果这个数组是 [a1, a2, a3, ... , an] 那么数组 [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] 中应该有且仅有 k 个不同整数.
- 如果存在多种答案你只需实现并返回其中任意一种.
## 解题思路
- 先考虑 `k` 最大值的情况如果把末尾的较大值依次插入到前面的较小值中形成 `[1n2n-13n-2……]`这样排列 `k` 能取到最大值 `n-1` `k` 最小值的情况是 `[1234……n]``k` 取到的最小值是 1那么 `k` `[1n-1]` 之间取值该怎么排列呢先顺序排列 `[1234……n-k-1]`这里有 `n-k-1` 个数可以形成唯一一种差值剩下 `k+1` 个数形成 `k-1` 种差值
- 这又回到了 `k` 最大值的取法了`k` 取最大值的情况是 `n` 个数形成 `n-1` 个不同种的差值现在 `k+1` 个数需要形成 `k` 种不同的差值两者是同一个问题那么剩下 `k` 个数的排列方法是 `[n-kn-k+1n]`这里有 `k` 个数注意代码实现时注意 `k` 的奇偶性如果 `k` 是奇数,“对半穿插以后正好匹配完如果 `k` 是偶数对半处的数 `n-k+(k+1)/2`最后还需要单独加入到排列中
- 可能有读者会问了前面生成了 1 种差值后面这部分又生产了 `k` 种差值加起来不是 `k + 1` 种差值了么这种理解是错误的后面这段最后 2 个数字是 `n-k+(k+1)/2-1` `n-k+(k+1)/2`它们两者的差值是 1和第一段构造的排列差值是相同的都是 1所以第一段构造了 1 种差值第二段虽然构造了 `k` 但是需要去掉两段重复的差值 1所以最终差值种类还是 `1 + k - 1 = k`
## 代码
```go
package leetcode
func constructArray(n int, k int) []int {
res := []int{}
for i := 0; i < n-k-1; i++ {
res = append(res, i+1)
}
for i := n - k; i < n-k+(k+1)/2; i++ {
res = append(res, i)
res = append(res, 2*n-k-i)
}
if k%2 == 0 {
res = append(res, n-k+(k+1)/2)
}
return res
}
```