mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-05 08:27:30 +08:00
Add weekly-contest-214 solution
This commit is contained in:
@ -0,0 +1,62 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question1646 struct {
|
||||
para1646
|
||||
ans1646
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para1646 struct {
|
||||
n int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans1646 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem1646(t *testing.T) {
|
||||
|
||||
qs := []question1646{
|
||||
|
||||
{
|
||||
para1646{7},
|
||||
ans1646{3},
|
||||
},
|
||||
|
||||
{
|
||||
para1646{2},
|
||||
ans1646{1},
|
||||
},
|
||||
|
||||
{
|
||||
para1646{3},
|
||||
ans1646{2},
|
||||
},
|
||||
|
||||
{
|
||||
para1646{0},
|
||||
ans1646{0},
|
||||
},
|
||||
|
||||
{
|
||||
para1646{1},
|
||||
ans1646{1},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 1646------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans1646, q.para1646
|
||||
fmt.Printf("【input】:%v 【output】:%v \n", p, getMaximumGenerated(p.n))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
96
leetcode/1646.Get-Maximum-in-Generated-Array/README.md
Normal file
96
leetcode/1646.Get-Maximum-in-Generated-Array/README.md
Normal file
@ -0,0 +1,96 @@
|
||||
# [1646. Get Maximum in Generated Array](https://leetcode.com/problems/get-maximum-in-generated-array/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
You are given an integer `n`. An array `nums` of length `n + 1` is generated in the following way:
|
||||
|
||||
- `nums[0] = 0`
|
||||
- `nums[1] = 1`
|
||||
- `nums[2 * i] = nums[i]` when `2 <= 2 * i <= n`
|
||||
- `nums[2 * i + 1] = nums[i] + nums[i + 1]` when `2 <= 2 * i + 1 <= n`
|
||||
|
||||
Return *****the **maximum** integer in the array* `nums`.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```
|
||||
Input: n = 7
|
||||
Output: 3
|
||||
Explanation: According to the given rules:
|
||||
nums[0] = 0
|
||||
nums[1] = 1
|
||||
nums[(1 * 2) = 2] = nums[1] = 1
|
||||
nums[(1 * 2) + 1 = 3] = nums[1] + nums[2] = 1 + 1 = 2
|
||||
nums[(2 * 2) = 4] = nums[2] = 1
|
||||
nums[(2 * 2) + 1 = 5] = nums[2] + nums[3] = 1 + 2 = 3
|
||||
nums[(3 * 2) = 6] = nums[3] = 2
|
||||
nums[(3 * 2) + 1 = 7] = nums[3] + nums[4] = 2 + 1 = 3
|
||||
Hence, nums = [0,1,1,2,1,3,2,3], and the maximum is 3.
|
||||
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```
|
||||
Input: n = 2
|
||||
Output: 1
|
||||
Explanation: According to the given rules, the maximum between nums[0], nums[1], and nums[2] is 1.
|
||||
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```
|
||||
Input: n = 3
|
||||
Output: 2
|
||||
Explanation: According to the given rules, the maximum between nums[0], nums[1], nums[2], and nums[3] is 2.
|
||||
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `0 <= n <= 100`
|
||||
|
||||
## 题目大意
|
||||
|
||||
给你一个整数 n 。按下述规则生成一个长度为 n + 1 的数组 nums :
|
||||
|
||||
- nums[0] = 0
|
||||
- nums[1] = 1
|
||||
- 当 2 <= 2 * i <= n 时,nums[2 * i] = nums[i]
|
||||
- 当 2 <= 2 * i + 1 <= n 时,nums[2 * i + 1] = nums[i] + nums[i + 1]
|
||||
|
||||
返回生成数组 nums 中的 最大值。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个 n + 1 的数组,并按照生成规则生成这个数组,求出这个数组中的最大值。
|
||||
- 简单题,按照题意生成数组,边生成边记录和更新最大值即可。
|
||||
- 注意边界条件,当 n 为 0 的时候,数组里面只有一个元素 0 。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
func getMaximumGenerated(n int) int {
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
nums, max := make([]int, n+1), 0
|
||||
nums[0], nums[1] = 0, 1
|
||||
for i := 0; i <= n; i++ {
|
||||
if nums[i] > max {
|
||||
max = nums[i]
|
||||
}
|
||||
if 2*i >= 2 && 2*i <= n {
|
||||
nums[2*i] = nums[i]
|
||||
}
|
||||
if 2*i+1 >= 2 && 2*i+1 <= n {
|
||||
nums[2*i+1] = nums[i] + nums[i+1]
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
```
|
@ -1,7 +1,6 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
@ -11,7 +10,6 @@ func minDeletions(s string) int {
|
||||
frequency[s[i]-'a']++
|
||||
}
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(frequency)))
|
||||
fmt.Printf("%v\n", frequency)
|
||||
for i := 1; i <= 25; i++ {
|
||||
if frequency[i] == frequency[i-1] && frequency[i] != 0 {
|
||||
res++
|
@ -0,0 +1,62 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question1647 struct {
|
||||
para1647
|
||||
ans1647
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para1647 struct {
|
||||
s string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans1647 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem1647(t *testing.T) {
|
||||
|
||||
qs := []question1647{
|
||||
|
||||
{
|
||||
para1647{"aab"},
|
||||
ans1647{0},
|
||||
},
|
||||
|
||||
{
|
||||
para1647{"aaabbbcc"},
|
||||
ans1647{2},
|
||||
},
|
||||
|
||||
{
|
||||
para1647{"ceabaacb"},
|
||||
ans1647{2},
|
||||
},
|
||||
|
||||
{
|
||||
para1647{""},
|
||||
ans1647{0},
|
||||
},
|
||||
|
||||
{
|
||||
para1647{"abcabc"},
|
||||
ans1647{3},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 1647------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans1647, q.para1647
|
||||
fmt.Printf("【input】:%v 【output】:%v \n", p, minDeletions(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
# [1647. Minimum Deletions to Make Character Frequencies Unique](https://leetcode.com/problems/minimum-deletions-to-make-character-frequencies-unique/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
A string `s` is called **good** if there are no two different characters in `s` that have the same **frequency**.
|
||||
|
||||
Given a string `s`, return *the **minimum** number of characters you need to delete to make* `s` ***good**.*
|
||||
|
||||
The **frequency** of a character in a string is the number of times it appears in the string. For example, in the string `"aab"`, the **frequency** of `'a'` is `2`, while the **frequency** of `'b'` is `1`.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```
|
||||
Input: s = "aab"
|
||||
Output: 0
|
||||
Explanation: s is already good.
|
||||
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```
|
||||
Input: s = "aaabbbcc"
|
||||
Output: 2
|
||||
Explanation: You can delete two 'b's resulting in the good string "aaabcc".
|
||||
Another way it to delete one 'b' and one 'c' resulting in the good string "aaabbc".
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```
|
||||
Input: s = "ceabaacb"
|
||||
Output: 2
|
||||
Explanation: You can delete both 'c's resulting in the good string "eabaab".
|
||||
Note that we only care about characters that are still in the string at the end (i.e. frequency of 0 is ignored).
|
||||
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `1 <= s.length <= 105`
|
||||
- `s` contains only lowercase English letters.
|
||||
|
||||
## 题目大意
|
||||
|
||||
如果字符串 s 中 不存在 两个不同字符 频次 相同的情况,就称 s 是 优质字符串 。
|
||||
|
||||
给你一个字符串 s,返回使 s 成为优质字符串需要删除的最小字符数。
|
||||
|
||||
字符串中字符的 频次 是该字符在字符串中的出现次数。例如,在字符串 "aab" 中,'a' 的频次是 2,而 'b' 的频次是 1 。
|
||||
|
||||
**提示:**
|
||||
|
||||
- `1 <= s.length <= 105`
|
||||
- `s` 仅含小写英文字母
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个字符串 s,要求输出使 s 变成“优质字符串”需要删除的最小字符数。“优质字符串”的定义是:字符串 s 中不存在频次相同的两个不同字符。
|
||||
- 首先将 26 个字母在字符串中的频次分别统计出来,然后把频次从大到小排列,从频次大的开始,依次调整:例如,假设前一个和后一个频次相等,就把前一个字符删除一个,频次减一,再次排序,如果频次还相等,继续调整,如果频次不同了,游标往后移,继续调整后面的频次。直到所有的频次都不同了,就可以输出最终结果了。
|
||||
- 这里需要注意频次为 0 的情况,即字母都被删光了。频次为 0 以后,就不需要再比较了。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
func minDeletions(s string) int {
|
||||
frequency, res := make([]int, 26), 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
frequency[s[i]-'a']++
|
||||
}
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(frequency)))
|
||||
for i := 1; i <= 25; i++ {
|
||||
if frequency[i] == frequency[i-1] && frequency[i] != 0 {
|
||||
res++
|
||||
frequency[i]--
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(frequency)))
|
||||
i--
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
@ -4,7 +4,55 @@ import (
|
||||
"container/heap"
|
||||
)
|
||||
|
||||
// 解法一 贪心 + 二分搜索
|
||||
func maxProfit(inventory []int, orders int) int {
|
||||
maxItem, thresholdValue, count, res, mod := 0, -1, 0, 0, 1000000007
|
||||
for i := 0; i < len(inventory); i++ {
|
||||
if inventory[i] > maxItem {
|
||||
maxItem = inventory[i]
|
||||
}
|
||||
}
|
||||
low, high := 0, maxItem
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
for i := 0; i < len(inventory); i++ {
|
||||
count += max(inventory[i]-mid, 0)
|
||||
}
|
||||
if count <= orders {
|
||||
thresholdValue = mid
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
count = 0
|
||||
}
|
||||
count = 0
|
||||
for i := 0; i < len(inventory); i++ {
|
||||
count += max(inventory[i]-thresholdValue, 0)
|
||||
}
|
||||
count = orders - count
|
||||
for i := 0; i < len(inventory); i++ {
|
||||
if inventory[i] >= thresholdValue {
|
||||
if count > 0 {
|
||||
res += (thresholdValue + inventory[i]) * (inventory[i] - thresholdValue + 1) / 2
|
||||
count--
|
||||
} else {
|
||||
res += (thresholdValue + 1 + inventory[i]) * (inventory[i] - thresholdValue) / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
return res % mod
|
||||
}
|
||||
|
||||
func max(a int, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// 解法二 优先队列,超时!
|
||||
func maxProfit_(inventory []int, orders int) int {
|
||||
res, mod := 0, 1000000007
|
||||
q := PriorityQueue{}
|
||||
for i := 0; i < len(inventory); i++ {
|
@ -0,0 +1,63 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question1648 struct {
|
||||
para1648
|
||||
ans1648
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para1648 struct {
|
||||
inventory []int
|
||||
orders int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans1648 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem1648(t *testing.T) {
|
||||
|
||||
qs := []question1648{
|
||||
|
||||
{
|
||||
para1648{[]int{2, 3, 3, 4, 5}, 4},
|
||||
ans1648{16},
|
||||
},
|
||||
|
||||
{
|
||||
para1648{[]int{2, 5}, 4},
|
||||
ans1648{14},
|
||||
},
|
||||
|
||||
{
|
||||
para1648{[]int{3, 5}, 6},
|
||||
ans1648{19},
|
||||
},
|
||||
|
||||
{
|
||||
para1648{[]int{2, 8, 4, 10, 6}, 20},
|
||||
ans1648{110},
|
||||
},
|
||||
|
||||
{
|
||||
para1648{[]int{1000000000}, 1000000000},
|
||||
ans1648{21},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 1648------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans1648, q.para1648
|
||||
fmt.Printf("【input】:%v 【output】:%v \n", p, maxProfit(p.inventory, p.orders))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
131
leetcode/1648.Sell-Diminishing-Valued-Colored-Balls/README.md
Normal file
131
leetcode/1648.Sell-Diminishing-Valued-Colored-Balls/README.md
Normal file
@ -0,0 +1,131 @@
|
||||
# [1648. Sell Diminishing-Valued Colored Balls](https://leetcode.com/problems/sell-diminishing-valued-colored-balls/)
|
||||
|
||||
|
||||
## 题目
|
||||
|
||||
You have an `inventory` of different colored balls, and there is a customer that wants `orders` balls of **any** color.
|
||||
|
||||
The customer weirdly values the colored balls. Each colored ball's value is the number of balls **of that color** you currently have in your `inventory`. For example, if you own `6` yellow balls, the customer would pay `6` for the first yellow ball. After the transaction, there are only `5` yellow balls left, so the next yellow ball is then valued at `5` (i.e., the value of the balls decreases as you sell more to the customer).
|
||||
|
||||
You are given an integer array, `inventory`, where `inventory[i]` represents the number of balls of the `ith` color that you initially own. You are also given an integer `orders`, which represents the total number of balls that the customer wants. You can sell the balls **in any order**.
|
||||
|
||||
Return *the **maximum** total value that you can attain after selling* `orders` *colored balls*. As the answer may be too large, return it **modulo** `109 + 7`.
|
||||
|
||||
**Example 1:**
|
||||
|
||||

|
||||
|
||||
```
|
||||
Input: inventory = [2,5], orders = 4
|
||||
Output: 14
|
||||
Explanation: Sell the 1st color 1 time (2) and the 2nd color 3 times (5 + 4 + 3).
|
||||
The maximum total value is 2 + 5 + 4 + 3 = 14.
|
||||
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```
|
||||
Input: inventory = [3,5], orders = 6
|
||||
Output: 19
|
||||
Explanation: Sell the 1st color 2 times (3 + 2) and the 2nd color 4 times (5 + 4 + 3 + 2).
|
||||
The maximum total value is 3 + 2 + 5 + 4 + 3 + 2 = 19.
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```
|
||||
Input: inventory = [2,8,4,10,6], orders = 20
|
||||
Output: 110
|
||||
```
|
||||
|
||||
**Example 4:**
|
||||
|
||||
```
|
||||
Input: inventory = [1000000000], orders = 1000000000
|
||||
Output: 21
|
||||
Explanation: Sell the 1st color 1000000000 times for a total value of 500000000500000000. 500000000500000000 modulo 109 + 7 = 21.
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `1 <= inventory.length <= 10^5`
|
||||
- `1 <= inventory[i] <= 10^9`
|
||||
- `1 <= orders <= min(sum(inventory[i]), 10^9)`
|
||||
|
||||
## 题目大意
|
||||
|
||||
你有一些球的库存 inventory ,里面包含着不同颜色的球。一个顾客想要 任意颜色 总数为 orders 的球。这位顾客有一种特殊的方式衡量球的价值:每个球的价值是目前剩下的 同色球 的数目。比方说还剩下 6 个黄球,那么顾客买第一个黄球的时候该黄球的价值为 6 。这笔交易以后,只剩下 5 个黄球了,所以下一个黄球的价值为 5 (也就是球的价值随着顾客购买同色球是递减的)
|
||||
|
||||
给你整数数组 inventory ,其中 inventory[i] 表示第 i 种颜色球一开始的数目。同时给你整数 orders ,表示顾客总共想买的球数目。你可以按照 任意顺序 卖球。请你返回卖了 orders 个球以后 最大 总价值之和。由于答案可能会很大,请你返回答案对 109 + 7 取余数 的结果。
|
||||
|
||||
提示:
|
||||
|
||||
- 1 <= inventory.length <= 10^5
|
||||
- 1 <= inventory[i] <= 10^9
|
||||
- 1 <= orders <= min(sum(inventory[i]), 10^9)
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个 `inventory` 数组和 `orders` 次操作,要求输出数组中前 `orders` 大个元素累加和。需要注意的是,每累加一个元素 `inventory[i]`,这个元素都会减一,下次再累加的时候,需要选取更新以后的数组的最大值。
|
||||
- 拿到这个题目以后很容易想到优先队列,建立大根堆以后,`pop` 出当前最大值 `maxItem`,累加,以后把 `maxItem` 减一再 `push` 回去。循环执行 `orders` 次以后即是最终结果。题目是这个意思,但是我们不能这么写代码,因为题目条件里面给出了 `orders` 的数据大小。orders 最大为 10^9。按照优先队列的这个方法一定会超时,时间复杂度为 O(orders⋅logn)。那就换一个思路。优先队列这个思路中,重复操作了 `orders` 次,其实在这些操作中,有一些是没有必要的废操作。这些大量的“废”操作导致了超时。试想,在 `orders` 次操作中,能否合并 `n` 个 `pop` 操作,一口气先 `pop` 掉 `n` 个前 `n` 大的数呢?这个是可行的,因为每次 `pop` 出去,元素都只会减一,这个是非常有规律的。
|
||||
- 为了接下来的描述更加清晰易懂,还需要再定义 1 个值, `thresholdValue` 为操作 `n` 次以后,当前 `inventory` 数组的最大值。关于 `thresholdValue` 的理解,这里要说明一下。 `thresholdValue` 的来源有 2 种,一种是本来数组里面就有这个值,还有一种来源是 `inventory[i]` 元素减少到了 `thresholdValue` 这个值。举个例子:原始数组是 [2,3,3,4,5],`orders` = 4,取 4 次以后,剩下的数组是 [2,2,3,3,3]。3 个 3 里面其中一个 3 就来自于 `4-1=3`,或者 `5-2=3`。
|
||||
- 用二分搜索在 [0,max(`inventory`)] 区间内找到这个 `thresholdValue` 值,能满足下列不等式的最小 `thresholdValue` 值:
|
||||
|
||||
$$\sum_{inventory[i]\geqslant thresholdValue}^{} \left ( inventory[i] - thresholdValue \right )\leqslant orders$$
|
||||
|
||||
`thresholdValue` 越小,不等式左边的值越大,随着 `thresholdValue` 的增大,不等式左边的值越来越小,直到刚刚能小于等于 `orders`。求出了 `thresholdValue` 值以后,还需要再判断有多少值等于 `thresholdValue - 1` 值了。
|
||||
|
||||

|
||||
|
||||
- 还是举上面的例子,原始数组是 [2,3,3,4,5],`orders` = 4,我们可以求得 `thresholdValue` = 3 。`inventory[i]` > `thresholdValue` 的那部分 100% 的要取走,`thresholdValue` 就像一个水平面,突出水平面的那些都要拿走,每列的值按照等差数列求和公式计算即可。但是 `orders` - `thresholdValue` = 1,说明水平面以下还要拿走一个,即 `thresholdValue` 线下的虚线框里面的那 4 个球,还需要任意取走一个。最后总的结果是这 2 部分的总和,( ( 5 + 4 ) + 4 ) + 3 = 16 。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
)
|
||||
|
||||
// 解法一 贪心 + 二分搜索
|
||||
func maxProfit(inventory []int, orders int) int {
|
||||
maxItem, thresholdValue, count, res, mod := 0, -1, 0, 0, 1000000007
|
||||
for i := 0; i < len(inventory); i++ {
|
||||
if inventory[i] > maxItem {
|
||||
maxItem = inventory[i]
|
||||
}
|
||||
}
|
||||
low, high := 0, maxItem
|
||||
for low <= high {
|
||||
mid := low + ((high - low) >> 1)
|
||||
for i := 0; i < len(inventory); i++ {
|
||||
count += max(inventory[i]-mid, 0)
|
||||
}
|
||||
if count <= orders {
|
||||
thresholdValue = mid
|
||||
high = mid - 1
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
count = 0
|
||||
}
|
||||
count = 0
|
||||
for i := 0; i < len(inventory); i++ {
|
||||
count += max(inventory[i]-thresholdValue, 0)
|
||||
}
|
||||
count = orders - count
|
||||
for i := 0; i < len(inventory); i++ {
|
||||
if inventory[i] >= thresholdValue {
|
||||
if count > 0 {
|
||||
res += (thresholdValue + inventory[i]) * (inventory[i] - thresholdValue + 1) / 2
|
||||
count--
|
||||
} else {
|
||||
res += (thresholdValue + 1 + inventory[i]) * (inventory[i] - thresholdValue) / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
return res % mod
|
||||
}
|
||||
```
|
@ -0,0 +1,106 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// 解法一 线段树 SegmentTree
|
||||
func createSortedArray(instructions []int) int {
|
||||
if len(instructions) == 0 {
|
||||
return 0
|
||||
}
|
||||
st, res, mod := template.SegmentCountTree{}, 0, 1000000007
|
||||
numsMap, numsArray, tmpArray := discretization1649(instructions)
|
||||
// 初始化线段树,节点内的值都赋值为 0,即计数为 0
|
||||
st.Init(tmpArray, func(i, j int) int {
|
||||
return 0
|
||||
})
|
||||
for i := 0; i < len(instructions); i++ {
|
||||
strictlyLessThan := st.Query(0, numsMap[instructions[i]]-1)
|
||||
strictlyGreaterThan := st.Query(numsMap[instructions[i]]+1, numsArray[len(numsArray)-1])
|
||||
res = (res + min(strictlyLessThan, strictlyGreaterThan)) % mod
|
||||
st.UpdateCount(numsMap[instructions[i]])
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func discretization1649(instructions []int) (map[int]int, []int, []int) {
|
||||
tmpArray, numsArray, numsMap := []int{}, []int{}, map[int]int{}
|
||||
for i := 0; i < len(instructions); i++ {
|
||||
numsMap[instructions[i]] = instructions[i]
|
||||
}
|
||||
for _, v := range numsMap {
|
||||
numsArray = append(numsArray, v)
|
||||
}
|
||||
sort.Ints(numsArray)
|
||||
for i, num := range numsArray {
|
||||
numsMap[num] = i
|
||||
}
|
||||
for i := range numsArray {
|
||||
tmpArray = append(tmpArray, i)
|
||||
}
|
||||
return numsMap, numsArray, tmpArray
|
||||
}
|
||||
|
||||
func min(a int, b int) int {
|
||||
if a > b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// 解法二 树状数组 Binary Indexed Tree
|
||||
func createSortedArray1(instructions []int) int {
|
||||
b := newBIT(make([]int, 100001))
|
||||
var res int
|
||||
cnt := map[int]int{}
|
||||
for i, n := range instructions {
|
||||
less := b.get(n - 1)
|
||||
greater := i - less - cnt[n]
|
||||
res = (res + min(less, greater)) % (1e9 + 7)
|
||||
b.update(n, 1)
|
||||
cnt[n]++
|
||||
}
|
||||
|
||||
return res % (1e9 + 7)
|
||||
}
|
||||
|
||||
func max(x, y int) int {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
type BIT struct {
|
||||
data []int
|
||||
}
|
||||
|
||||
func newBIT(nums []int) *BIT {
|
||||
data := make([]int, len(nums)+1)
|
||||
b := &BIT{data}
|
||||
for i, n := range nums {
|
||||
b.update(i, n)
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *BIT) update(i, num int) {
|
||||
i++
|
||||
for i < len(b.data) {
|
||||
b.data[i] += num
|
||||
i += (i & -i)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BIT) get(i int) int {
|
||||
i++
|
||||
var sum int
|
||||
for i > 0 {
|
||||
sum += b.data[i]
|
||||
i -= (i & -i)
|
||||
}
|
||||
return sum
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question1649 struct {
|
||||
para1649
|
||||
ans1649
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para1649 struct {
|
||||
instructions []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans1649 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem1649(t *testing.T) {
|
||||
|
||||
qs := []question1649{
|
||||
|
||||
{
|
||||
para1649{[]int{1, 5, 6, 2}},
|
||||
ans1649{1},
|
||||
},
|
||||
|
||||
{
|
||||
para1649{[]int{1, 2, 3, 6, 5, 4}},
|
||||
ans1649{3},
|
||||
},
|
||||
|
||||
{
|
||||
para1649{[]int{1, 3, 3, 3, 2, 4, 2, 1, 2}},
|
||||
ans1649{4},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 1649------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans1649, q.para1649
|
||||
fmt.Printf("【input】:%v 【output】:%v \n", p, createSortedArray(p.instructions))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
189
leetcode/1649.Create-Sorted-Array-through-Instructions/README.md
Normal file
189
leetcode/1649.Create-Sorted-Array-through-Instructions/README.md
Normal file
@ -0,0 +1,189 @@
|
||||
# [1649. Create Sorted Array through Instructions](https://leetcode.com/problems/create-sorted-array-through-instructions/)
|
||||
|
||||
## 题目
|
||||
|
||||
Given an integer array `instructions`, you are asked to create a sorted array from the elements in `instructions`. You start with an empty container `nums`. For each element from **left to right** in `instructions`, insert it into `nums`. The **cost** of each insertion is the **minimum** of the following:
|
||||
|
||||
- The number of elements currently in `nums` that are **strictly less than** `instructions[i]`.
|
||||
- The number of elements currently in `nums` that are **strictly greater than** `instructions[i]`.
|
||||
|
||||
For example, if inserting element `3` into `nums = [1,2,3,5]`, the **cost** of insertion is `min(2, 1)` (elements `1` and `2` are less than `3`, element `5` is greater than `3`) and `nums` will become `[1,2,3,3,5]`.
|
||||
|
||||
Return *the **total cost** to insert all elements from* `instructions` *into* `nums`. Since the answer may be large, return it **modulo** `10^9 + 7`
|
||||
|
||||
**Example 1:**
|
||||
|
||||
```
|
||||
Input: instructions = [1,5,6,2]
|
||||
Output: 1
|
||||
Explanation: Begin with nums = [].
|
||||
Insert 1 with cost min(0, 0) = 0, now nums = [1].
|
||||
Insert 5 with cost min(1, 0) = 0, now nums = [1,5].
|
||||
Insert 6 with cost min(2, 0) = 0, now nums = [1,5,6].
|
||||
Insert 2 with cost min(1, 2) = 1, now nums = [1,2,5,6].
|
||||
The total cost is 0 + 0 + 0 + 1 = 1.
|
||||
```
|
||||
|
||||
**Example 2:**
|
||||
|
||||
```
|
||||
Input: instructions = [1,2,3,6,5,4]
|
||||
Output: 3
|
||||
Explanation: Begin with nums = [].
|
||||
Insert 1 with cost min(0, 0) = 0, now nums = [1].
|
||||
Insert 2 with cost min(1, 0) = 0, now nums = [1,2].
|
||||
Insert 3 with cost min(2, 0) = 0, now nums = [1,2,3].
|
||||
Insert 6 with cost min(3, 0) = 0, now nums = [1,2,3,6].
|
||||
Insert 5 with cost min(3, 1) = 1, now nums = [1,2,3,5,6].
|
||||
Insert 4 with cost min(3, 2) = 2, now nums = [1,2,3,4,5,6].
|
||||
The total cost is 0 + 0 + 0 + 0 + 1 + 2 = 3.
|
||||
```
|
||||
|
||||
**Example 3:**
|
||||
|
||||
```
|
||||
Input: instructions = [1,3,3,3,2,4,2,1,2]
|
||||
Output: 4
|
||||
Explanation: Begin with nums = [].
|
||||
Insert 1 with cost min(0, 0) = 0, now nums = [1].
|
||||
Insert 3 with cost min(1, 0) = 0, now nums = [1,3].
|
||||
Insert 3 with cost min(1, 0) = 0, now nums = [1,3,3].
|
||||
Insert 3 with cost min(1, 0) = 0, now nums = [1,3,3,3].
|
||||
Insert 2 with cost min(1, 3) = 1, now nums = [1,2,3,3,3].
|
||||
Insert 4 with cost min(5, 0) = 0, now nums = [1,2,3,3,3,4].
|
||||
Insert 2 with cost min(1, 4) = 1, now nums = [1,2,2,3,3,3,4].
|
||||
Insert 1 with cost min(0, 6) = 0, now nums = [1,1,2,2,3,3,3,4].
|
||||
Insert 2 with cost min(2, 4) = 2, now nums = [1,1,2,2,2,3,3,3,4].
|
||||
The total cost is 0 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + 2 = 4.
|
||||
```
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- `1 <= instructions.length <= 105`
|
||||
- `1 <= instructions[i] <= 105`
|
||||
|
||||
## 题目大意
|
||||
|
||||
给你一个整数数组 instructions ,你需要根据 instructions 中的元素创建一个有序数组。一开始你有一个空的数组 nums ,你需要 从左到右 遍历 instructions 中的元素,将它们依次插入 nums 数组中。每一次插入操作的 代价 是以下两者的 较小值 :
|
||||
|
||||
- nums 中 严格小于 instructions[i] 的数字数目。
|
||||
- nums 中 严格大于 instructions[i] 的数字数目。
|
||||
|
||||
比方说,如果要将 3 插入到 nums = [1,2,3,5] ,那么插入操作的 代价 为 min(2, 1) (元素 1 和 2 小于 3 ,元素 5 大于 3 ),插入后 nums 变成 [1,2,3,3,5] 。请你返回将 instructions 中所有元素依次插入 nums 后的 总最小代价 。由于答案会很大,请将它对 10^9 + 7 取余 后返回。
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个数组,要求将其中的元素从头开始往另外一个空数组中插入,每次插入前,累加代价值 cost = min(**strictly less than**, **strictly greater than**)。最后输出累加值。
|
||||
- 这一题虽然是 Hard 题,但是读完题以后就可以判定这是模板题了。可以用线段树和树状数组来解决。这里简单说说线段树的思路吧,先将待插入的数组排序,获得总的区间。每次循环做 4 步:2 次 `query` 分别得到 `strictlyLessThan` 和 `strictlyGreaterThan` ,再比较出两者中的最小值累加,最后一步就是 `update`。
|
||||
- 由于题目给的数据比较大,所以建立线段树之前记得要先离散化。这一题核心代码不超过 10 行,其他的都是模板代码。具体实现见代码。
|
||||
|
||||
## 代码
|
||||
|
||||
```go
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// 解法一 线段树 SegmentTree
|
||||
func createSortedArray(instructions []int) int {
|
||||
if len(instructions) == 0 {
|
||||
return 0
|
||||
}
|
||||
st, res, mod := template.SegmentCountTree{}, 0, 1000000007
|
||||
numsMap, numsArray, tmpArray := discretization1649(instructions)
|
||||
// 初始化线段树,节点内的值都赋值为 0,即计数为 0
|
||||
st.Init(tmpArray, func(i, j int) int {
|
||||
return 0
|
||||
})
|
||||
for i := 0; i < len(instructions); i++ {
|
||||
strictlyLessThan := st.Query(0, numsMap[instructions[i]]-1)
|
||||
strictlyGreaterThan := st.Query(numsMap[instructions[i]]+1, numsArray[len(numsArray)-1])
|
||||
res = (res + min(strictlyLessThan, strictlyGreaterThan)) % mod
|
||||
st.UpdateCount(numsMap[instructions[i]])
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func discretization1649(instructions []int) (map[int]int, []int, []int) {
|
||||
tmpArray, numsArray, numsMap := []int{}, []int{}, map[int]int{}
|
||||
for i := 0; i < len(instructions); i++ {
|
||||
numsMap[instructions[i]] = instructions[i]
|
||||
}
|
||||
for _, v := range numsMap {
|
||||
numsArray = append(numsArray, v)
|
||||
}
|
||||
sort.Ints(numsArray)
|
||||
for i, num := range numsArray {
|
||||
numsMap[num] = i
|
||||
}
|
||||
for i := range numsArray {
|
||||
tmpArray = append(tmpArray, i)
|
||||
}
|
||||
return numsMap, numsArray, tmpArray
|
||||
}
|
||||
|
||||
func min(a int, b int) int {
|
||||
if a > b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// 解法二 树状数组 Binary Indexed Tree
|
||||
func createSortedArray1(instructions []int) int {
|
||||
b := newBIT(make([]int, 100001))
|
||||
var res int
|
||||
cnt := map[int]int{}
|
||||
for i, n := range instructions {
|
||||
less := b.get(n - 1)
|
||||
greater := i - less - cnt[n]
|
||||
res = (res + min(less, greater)) % (1e9 + 7)
|
||||
b.update(n, 1)
|
||||
cnt[n]++
|
||||
}
|
||||
|
||||
return res % (1e9 + 7)
|
||||
}
|
||||
|
||||
func max(x, y int) int {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
type BIT struct {
|
||||
data []int
|
||||
}
|
||||
|
||||
func newBIT(nums []int) *BIT {
|
||||
data := make([]int, len(nums)+1)
|
||||
b := &BIT{data}
|
||||
for i, n := range nums {
|
||||
b.update(i, n)
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *BIT) update(i, num int) {
|
||||
i++
|
||||
for i < len(b.data) {
|
||||
b.data[i] += num
|
||||
i += (i & -i)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BIT) get(i int) int {
|
||||
i++
|
||||
var sum int
|
||||
for i > 0 {
|
||||
sum += b.data[i]
|
||||
i -= (i & -i)
|
||||
}
|
||||
return sum
|
||||
}
|
||||
```
|
@ -1,62 +0,0 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question5561 struct {
|
||||
para5561
|
||||
ans5561
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para5561 struct {
|
||||
n int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans5561 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem5561(t *testing.T) {
|
||||
|
||||
qs := []question5561{
|
||||
|
||||
{
|
||||
para5561{7},
|
||||
ans5561{3},
|
||||
},
|
||||
|
||||
{
|
||||
para5561{2},
|
||||
ans5561{1},
|
||||
},
|
||||
|
||||
{
|
||||
para5561{3},
|
||||
ans5561{2},
|
||||
},
|
||||
|
||||
{
|
||||
para5561{0},
|
||||
ans5561{0},
|
||||
},
|
||||
|
||||
{
|
||||
para5561{1},
|
||||
ans5561{1},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 5561------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans5561, q.para5561
|
||||
fmt.Printf("【input】:%v 【output】:%v \n", p, getMaximumGenerated(p.n))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question5562 struct {
|
||||
para5562
|
||||
ans5562
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para5562 struct {
|
||||
s string
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans5562 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem5562(t *testing.T) {
|
||||
|
||||
qs := []question5562{
|
||||
|
||||
{
|
||||
para5562{"aab"},
|
||||
ans5562{0},
|
||||
},
|
||||
|
||||
{
|
||||
para5562{"aaabbbcc"},
|
||||
ans5562{2},
|
||||
},
|
||||
|
||||
{
|
||||
para5562{"ceabaacb"},
|
||||
ans5562{2},
|
||||
},
|
||||
|
||||
{
|
||||
para5562{""},
|
||||
ans5562{0},
|
||||
},
|
||||
|
||||
{
|
||||
para5562{"abcabc"},
|
||||
ans5562{3},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 5562------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans5562, q.para5562
|
||||
fmt.Printf("【input】:%v 【output】:%v \n", p, minDeletions(p.s))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question5563 struct {
|
||||
para5563
|
||||
ans5563
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para5563 struct {
|
||||
inventory []int
|
||||
orders int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans5563 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem5563(t *testing.T) {
|
||||
|
||||
qs := []question5563{
|
||||
|
||||
{
|
||||
para5563{[]int{2, 5}, 4},
|
||||
ans5563{14},
|
||||
},
|
||||
|
||||
{
|
||||
para5563{[]int{3, 5}, 6},
|
||||
ans5563{19},
|
||||
},
|
||||
|
||||
{
|
||||
para5563{[]int{2, 8, 4, 10, 6}, 20},
|
||||
ans5563{110},
|
||||
},
|
||||
|
||||
{
|
||||
para5563{[]int{1000000000}, 1000000000},
|
||||
ans5563{21},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 5563------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans5563, q.para5563
|
||||
fmt.Printf("【input】:%v 【output】:%v \n", p, maxProfit(p.inventory, p.orders))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
Reference in New Issue
Block a user