Add solution 0097、0523、0525、1465、1744

This commit is contained in:
YDZ
2021-06-04 16:22:35 +08:00
parent c0191c235d
commit cc78fdd0ef
42 changed files with 1447 additions and 173 deletions

View File

@ -0,0 +1,35 @@
package leetcode
func isInterleave(s1 string, s2 string, s3 string) bool {
if len(s1)+len(s2) != len(s3) {
return false
}
visited := make(map[int]bool)
return dfs(s1, s2, s3, 0, 0, visited)
}
func dfs(s1, s2, s3 string, p1, p2 int, visited map[int]bool) bool {
if p1+p2 == len(s3) {
return true
}
if _, ok := visited[(p1*len(s3))+p2]; ok {
return false
}
visited[(p1*len(s3))+p2] = true
var match1, match2 bool
if p1 < len(s1) && s3[p1+p2] == s1[p1] {
match1 = true
}
if p2 < len(s2) && s3[p1+p2] == s2[p2] {
match2 = true
}
if match1 && match2 {
return dfs(s1, s2, s3, p1+1, p2, visited) || dfs(s1, s2, s3, p1, p2+1, visited)
} else if match1 {
return dfs(s1, s2, s3, p1+1, p2, visited)
} else if match2 {
return dfs(s1, s2, s3, p1, p2+1, visited)
} else {
return false
}
}

View File

@ -0,0 +1,54 @@
package leetcode
import (
"fmt"
"testing"
)
type question97 struct {
para97
ans97
}
// para 是参数
// one 代表第一个参数
type para97 struct {
s1 string
s2 string
s3 string
}
// ans 是答案
// one 代表第一个答案
type ans97 struct {
one bool
}
func Test_Problem97(t *testing.T) {
qs := []question97{
{
para97{"aabcc", "dbbca", "aadbbcbcac"},
ans97{true},
},
{
para97{"aabcc", "dbbca", "aadbbbaccc"},
ans97{false},
},
{
para97{"", "", ""},
ans97{true},
},
}
fmt.Printf("------------------------Leetcode Problem 97------------------------\n")
for _, q := range qs {
_, p := q.ans97, q.para97
fmt.Printf("【input】:%v 【output】:%v\n", p, isInterleave(p.s1, p.s2, p.s3))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,104 @@
# [97. Interleaving String](https://leetcode.com/problems/interleaving-string/)
## 题目
Given strings `s1`, `s2`, and `s3`, find whether `s3` is formed by an **interleaving** of `s1` and `s2`.
An **interleaving** of two strings `s` and `t` is a configuration where they are divided into **non-empty** substrings such that:
- `s = s1 + s2 + ... + sn`
- `t = t1 + t2 + ... + tm`
- `|n - m| <= 1`
- The **interleaving** is `s1 + t1 + s2 + t2 + s3 + t3 + ...` or `t1 + s1 + t2 + s2 + t3 + s3 + ...`
**Note:** `a + b` is the concatenation of strings `a` and `b`.
**Example 1:**
![https://assets.leetcode.com/uploads/2020/09/02/interleave.jpg](https://assets.leetcode.com/uploads/2020/09/02/interleave.jpg)
```
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true
```
**Example 2:**
```
Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
Output: false
```
**Example 3:**
```
Input: s1 = "", s2 = "", s3 = ""
Output: true
```
**Constraints:**
- `0 <= s1.length, s2.length <= 100`
- `0 <= s3.length <= 200`
- `s1`, `s2`, and `s3` consist of lowercase English letters.
**Follow up:** Could you solve it using only `O(s2.length)` additional memory space?
## 题目大意
给定三个字符串 s1、s2、s3请你帮忙验证 s3 是否是由 s1  s2 交错 组成的。两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:
- s = s1 + s2 + ... + sn
- t = t1 + t2 + ... + tm
- |n - m| <= 1
- 交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...
提示a + b 意味着字符串 a 和 b 连接。
## 解题思路
- 深搜或者广搜暴力解题。笔者用深搜实现的。记录 s1 和 s2 串当前比较的位置 p1 和 p2。如果 s3[p1+p2] 的位置上等于 s1[p1] 或者 s2[p2] 代表能匹配上,那么继续往后移动 p1 和 p2 相应的位置。因为是交错字符串,所以判断匹配的位置是 s3[p1+p2] 的位置。如果仅仅这么写会超时s1 和 s2 两个字符串重复交叉判断的位置太多了。需要加上记忆化搜索。可以用 visited[i][j] 这样的二维数组来记录是否搜索过了。笔者为了压缩空间,将 i 和 j 编码压缩到一维数组了。i * len(s3) + j 是唯一下标,所以可以用这种方式存储是否搜索过。具体代码见下面的实现。
## 代码
```go
package leetcode
func isInterleave(s1 string, s2 string, s3 string) bool {
if len(s1)+len(s2) != len(s3) {
return false
}
visited := make(map[int]bool)
return dfs(s1, s2, s3, 0, 0, visited)
}
func dfs(s1, s2, s3 string, p1, p2 int, visited map[int]bool) bool {
if p1+p2 == len(s3) {
return true
}
if _, ok := visited[(p1*len(s3))+p2]; ok {
return false
}
visited[(p1*len(s3))+p2] = true
var match1, match2 bool
if p1 < len(s1) && s3[p1+p2] == s1[p1] {
match1 = true
}
if p2 < len(s2) && s3[p1+p2] == s2[p2] {
match2 = true
}
if match1 && match2 {
return dfs(s1, s2, s3, p1+1, p2, visited) || dfs(s1, s2, s3, p1, p2+1, visited)
} else if match1 {
return dfs(s1, s2, s3, p1+1, p2, visited)
} else if match2 {
return dfs(s1, s2, s3, p1, p2+1, visited)
} else {
return false
}
}
```

View File

@ -0,0 +1,18 @@
package leetcode
func checkSubarraySum(nums []int, k int) bool {
m := make(map[int]int)
m[0] = -1
sum := 0
for i, n := range nums {
sum += n
if r, ok := m[sum%k]; ok {
if i-2 >= r {
return true
}
} else {
m[sum%k] = i
}
}
return false
}

View File

@ -0,0 +1,53 @@
package leetcode
import (
"fmt"
"testing"
)
type question523 struct {
para523
ans523
}
// para 是参数
// one 代表第一个参数
type para523 struct {
nums []int
k int
}
// ans 是答案
// one 代表第一个答案
type ans523 struct {
one bool
}
func Test_Problem523(t *testing.T) {
qs := []question523{
{
para523{[]int{23, 2, 4, 6, 7}, 6},
ans523{true},
},
{
para523{[]int{23, 2, 6, 4, 7}, 6},
ans523{true},
},
{
para523{[]int{23, 2, 6, 4, 7}, 13},
ans523{false},
},
}
fmt.Printf("------------------------Leetcode Problem 523------------------------\n")
for _, q := range qs {
_, p := q.ans523, q.para523
fmt.Printf("【input】:%v 【output】:%v\n", p, checkSubarraySum(p.nums, p.k))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,75 @@
# [523. Continuous Subarray Sum](https://leetcode.com/problems/continuous-subarray-sum/)
## 题目
Given an integer array `nums` and an integer `k`, return `true` *if* `nums` *has a continuous subarray of size **at least two** whose elements sum up to a multiple of* `k`*, or* `false` *otherwise*.
An integer `x` is a multiple of `k` if there exists an integer `n` such that `x = n * k`. `0` is **always** a multiple of `k`.
**Example 1:**
```
Input: nums = [23,2,4,6,7], k = 6
Output: true
Explanation: [2, 4] is a continuous subarray of size 2 whose elements sum up to 6.
```
**Example 2:**
```
Input: nums = [23,2,6,4,7], k = 6
Output: true
Explanation: [23, 2, 6, 4, 7] is an continuous subarray of size 5 whose elements sum up to 42.
42 is a multiple of 6 because 42 = 7 * 6 and 7 is an integer.
```
**Example 3:**
```
Input: nums = [23,2,6,4,7], k = 13
Output: false
```
**Constraints:**
- `1 <= nums.length <= 105`
- `0 <= nums[i] <= 109`
- `0 <= sum(nums[i]) <= 231 - 1`
- `1 <= k <= 231 - 1`
## 题目大意
给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:
- 子数组大小至少为 2 ,且
- 子数组元素总和为 k 的倍数。
如果存在,返回 true ;否则,返回 false 。如果存在一个整数 n ,令整数 x 符合 x = n * k ,则称 x 是 k 的一个倍数。
## 解题思路
- 简单题。题目只要求是否存在,不要求找出所有解。用一个变量 sum 记录累加和。子数组的元素和可以用前缀和相减得到,例如 [i,j] 区间内的元素和,可以由 prefixSum[j] - prefixSum[i] 得到。当 prefixSums[j]prefixSums[i] 为 k 的倍数时prefixSums[i] 和 prefixSums[j] 除以 k 的余数相同。因此只需要计算每个下标对应的前缀和除以 k 的余数即可,使用 map 存储每个余数第一次出现的下标即可。在 map 中如果存在相同余数的 key代表当前下标和 map 中这个 key 记录的下标可以满足总和为 k 的倍数这一条件。再判断一下能否满足大小至少为 2 的条件即可。用 2 个下标相减,长度大于等于 2 即满足条件,可以输出 true。
## 代码
```go
package leetcode
func checkSubarraySum(nums []int, k int) bool {
m := make(map[int]int)
m[0] = -1
sum := 0
for i, n := range nums {
sum += n
if r, ok := m[sum%k]; ok {
if i-2 >= r {
return true
}
} else {
m[sum%k] = i
}
}
return false
}
```

View File

@ -0,0 +1,27 @@
package leetcode
func findMaxLength(nums []int) int {
dict := map[int]int{}
dict[0] = -1
count, res := 0, 0
for i := 0; i < len(nums); i++ {
if nums[i] == 0 {
count--
} else {
count++
}
if idx, ok := dict[count]; ok {
res = max(res, i-idx)
} else {
dict[count] = i
}
}
return res
}
func max(a, b int) int {
if a > b {
return a
}
return b
}

View File

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

View File

@ -0,0 +1,67 @@
# [525. Contiguous Array](https://leetcode.com/problems/contiguous-array/)
## 题目
Given a binary array `nums`, return *the maximum length of a contiguous subarray with an equal number of* `0` *and* `1`.
**Example 1:**
```
Input: nums = [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with an equal number of 0 and 1.
```
**Example 2:**
```
Input: nums = [0,1,0]
Output: 2
Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.
```
**Constraints:**
- `1 <= nums.length <= 105`
- `nums[i]` is either `0` or `1`.
## 题目大意
给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。
## 解题思路
- 0 和 1 的数量相同可以转化为两者数量相差为 0如果将 0 看作为 -1那么原题转化为求最长连续子数组其元素和为 0 。又变成了区间内求和的问题,自然而然转换为前缀和来处理。假设连续子数组是 [i,j] 区间,这个区间内元素和为 0 意味着 prefixSum[j] - prefixSum[i] = 0也就是 prefixSum[i] = prefixSum[j]。不断累加前缀和,将每个前缀和存入 map 中。一旦某个 key 存在了,代表之前某个下标的前缀和和当前下标构成的区间,这段区间内的元素和为 0 。这个区间是所求。扫完整个数组,扫描过程中动态更新最大区间长度,扫描完成便可得到最大区间长度,即最长连续子数组。
## 代码
```go
package leetcode
func findMaxLength(nums []int) int {
dict := map[int]int{}
dict[0] = -1
count, res := 0, 0
for i := 0; i < len(nums); i++ {
if nums[i] == 0 {
count--
} else {
count++
}
if idx, ok := dict[count]; ok {
res = max(res, i-idx)
} else {
dict[count] = i
}
}
return res
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
```

View File

@ -0,0 +1,26 @@
package leetcode
import "sort"
func maxArea(h int, w int, horizontalCuts []int, verticalCuts []int) int {
sort.Ints(horizontalCuts)
sort.Ints(verticalCuts)
maxw, maxl := horizontalCuts[0], verticalCuts[0]
for i, c := range horizontalCuts[1:] {
if c-horizontalCuts[i] > maxw {
maxw = c - horizontalCuts[i]
}
}
if h-horizontalCuts[len(horizontalCuts)-1] > maxw {
maxw = h - horizontalCuts[len(horizontalCuts)-1]
}
for i, c := range verticalCuts[1:] {
if c-verticalCuts[i] > maxl {
maxl = c - verticalCuts[i]
}
}
if w-verticalCuts[len(verticalCuts)-1] > maxl {
maxl = w - verticalCuts[len(verticalCuts)-1]
}
return (maxw * maxl) % (1000000007)
}

View File

@ -0,0 +1,55 @@
package leetcode
import (
"fmt"
"testing"
)
type question1465 struct {
para1465
ans1465
}
// para 是参数
// one 代表第一个参数
type para1465 struct {
h int
w int
horizontalCuts []int
verticalCuts []int
}
// ans 是答案
// one 代表第一个答案
type ans1465 struct {
one int
}
func Test_Problem1465(t *testing.T) {
qs := []question1465{
{
para1465{5, 4, []int{1, 2, 4}, []int{1, 3}},
ans1465{4},
},
{
para1465{5, 4, []int{3, 1}, []int{1}},
ans1465{6},
},
{
para1465{5, 4, []int{3}, []int{3}},
ans1465{9},
},
}
fmt.Printf("------------------------Leetcode Problem 1465------------------------\n")
for _, q := range qs {
_, p := q.ans1465, q.para1465
fmt.Printf("【input】:%v 【output】:%v \n", p, maxArea(p.h, p.w, p.horizontalCuts, p.verticalCuts))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,89 @@
# [1465. Maximum Area of a Piece of Cake After Horizontal and Vertical Cuts](https://leetcode.com/problems/maximum-area-of-a-piece-of-cake-after-horizontal-and-vertical-cuts/)
## 题目
Given a rectangular cake with height `h` and width `w`, and two arrays of integers `horizontalCuts` and `verticalCuts` where `horizontalCuts[i]` is the distance from the top of the rectangular cake to the `ith` horizontal cut and similarly, `verticalCuts[j]` is the distance from the left of the rectangular cake to the `jth` vertical cut.
*Return the maximum area of a piece of cake after you cut at each horizontal and vertical position provided in the arrays `horizontalCuts` and `verticalCuts`.* Since the answer can be a huge number, return this modulo 10^9 + 7.
**Example 1:**
![https://assets.leetcode.com/uploads/2020/05/14/leetcode_max_area_2.png](https://assets.leetcode.com/uploads/2020/05/14/leetcode_max_area_2.png)
```
Input: h = 5, w = 4, horizontalCuts = [1,2,4], verticalCuts = [1,3]
Output: 4
Explanation: The figure above represents the given rectangular cake. Red lines are the horizontal and vertical cuts. After you cut the cake, the green piece of cake has the maximum area.
```
**Example 2:**
![https://assets.leetcode.com/uploads/2020/05/14/leetcode_max_area_3.png](https://assets.leetcode.com/uploads/2020/05/14/leetcode_max_area_3.png)
```
Input: h = 5, w = 4, horizontalCuts = [3,1], verticalCuts = [1]
Output: 6
Explanation: The figure above represents the given rectangular cake. Red lines are the horizontal and vertical cuts. After you cut the cake, the green and yellow pieces of cake have the maximum area.
```
**Example 3:**
```
Input: h = 5, w = 4, horizontalCuts = [3], verticalCuts = [3]
Output: 9
```
**Constraints:**
- `2 <= h, w <= 10^9`
- `1 <= horizontalCuts.length < min(h, 10^5)`
- `1 <= verticalCuts.length < min(w, 10^5)`
- `1 <= horizontalCuts[i] < h`
- `1 <= verticalCuts[i] < w`
- It is guaranteed that all elements in `horizontalCuts` are distinct.
- It is guaranteed that all elements in `verticalCuts` are distinct.
## 题目大意
矩形蛋糕的高度为 h 且宽度为 w给你两个整数数组 horizontalCuts 和 verticalCuts其中 horizontalCuts[i] 是从矩形蛋糕顶部到第  i 个水平切口的距离,类似地, verticalCuts[j] 是从矩形蛋糕的左侧到第 j 个竖直切口的距离。请你按数组 horizontalCuts 和 verticalCuts 中提供的水平和竖直位置切割后,请你找出 面积最大 的那份蛋糕,并返回其 面积 。由于答案可能是一个很大的数字,因此需要将结果对 10^9 + 7 取余后返回。
## 解题思路
- 读完题比较容易想到解题思路。找到水平切口最大的差值和竖直切口最大的差值,这 4 条边构成的矩形即为最大矩形。不过有特殊情况需要判断,切口除了题目给的切口坐标以外,默认还有 4 个切口,即蛋糕原始的 4 条边。如下图二,最大的矩形其实在切口之外。所以找水平切口最大差值和竖直切口最大差值需要考虑到蛋糕原始的 4 条边。
![https://img.halfrost.com/Leetcode/leetcode_1465.png](https://img.halfrost.com/Leetcode/leetcode_1465.png)
## 代码
```go
package leetcode
import "sort"
func maxArea(h int, w int, hcuts []int, vcuts []int) int {
sort.Ints(hcuts)
sort.Ints(vcuts)
maxw, maxl := hcuts[0], vcuts[0]
for i, c := range hcuts[1:] {
if c-hcuts[i] > maxw {
maxw = c - hcuts[i]
}
}
if h-hcuts[len(hcuts)-1] > maxw {
maxw = h - hcuts[len(hcuts)-1]
}
for i, c := range vcuts[1:] {
if c-vcuts[i] > maxl {
maxl = c - vcuts[i]
}
}
if w-vcuts[len(vcuts)-1] > maxl {
maxl = w - vcuts[len(vcuts)-1]
}
return (maxw * maxl) % (1000000007)
}
```

View File

@ -0,0 +1,23 @@
package leetcode
func canEat(candiesCount []int, queries [][]int) []bool {
n := len(candiesCount)
prefixSum := make([]int, n)
prefixSum[0] = candiesCount[0]
for i := 1; i < n; i++ {
prefixSum[i] = prefixSum[i-1] + candiesCount[i]
}
res := make([]bool, len(queries))
for i, q := range queries {
favoriteType, favoriteDay, dailyCap := q[0], q[1], q[2]
x1 := favoriteDay + 1
y1 := (favoriteDay + 1) * dailyCap
x2 := 1
if favoriteType > 0 {
x2 = prefixSum[favoriteType-1] + 1
}
y2 := prefixSum[favoriteType]
res[i] = !(x1 > y2 || y1 < x2)
}
return res
}

View File

@ -0,0 +1,48 @@
package leetcode
import (
"fmt"
"testing"
)
type question1744 struct {
para1744
ans1744
}
// para 是参数
// one 代表第一个参数
type para1744 struct {
candiesCount []int
queries [][]int
}
// ans 是答案
// one 代表第一个答案
type ans1744 struct {
one []bool
}
func Test_Problem1744(t *testing.T) {
qs := []question1744{
{
para1744{[]int{7, 4, 5, 3, 8}, [][]int{{0, 2, 2}, {4, 2, 4}, {2, 13, 1000000000}}},
ans1744{[]bool{true, false, true}},
},
{
para1744{[]int{5, 2, 6, 4, 1}, [][]int{{3, 1, 2}, {4, 10, 3}, {3, 10, 100}, {4, 100, 30}, {1, 3, 1}}},
ans1744{[]bool{false, true, true, false, false}},
},
}
fmt.Printf("------------------------Leetcode Problem 1744------------------------\n")
for _, q := range qs {
_, p := q.ans1744, q.para1744
fmt.Printf("【input】:%v 【output】:%v\n", p, canEat(p.candiesCount, p.queries))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,88 @@
# [1744. Can You Eat Your Favorite Candy on Your Favorite Day?](https://leetcode.com/problems/can-you-eat-your-favorite-candy-on-your-favorite-day/)
## 题目
You are given a **(0-indexed)** array of positive integers `candiesCount` where `candiesCount[i]` represents the number of candies of the `ith` type you have. You are also given a 2D array `queries` where `queries[i] = [favoriteTypei, favoriteDayi, dailyCapi]`.
You play a game with the following rules:
- You start eating candies on day **`0`**.
- You **cannot** eat **any** candy of type `i` unless you have eaten **all** candies of type `i - 1`.
- You must eat **at least** **one** candy per day until you have eaten all the candies.
Construct a boolean array `answer` such that `answer.length == queries.length` and `answer[i]` is `true` if you can eat a candy of type `favoriteTypei` on day `favoriteDayi` without eating **more than** `dailyCapi` candies on **any** day, and `false` otherwise. Note that you can eat different types of candy on the same day, provided that you follow rule 2.
Return *the constructed array* `answer`.
**Example 1:**
```
Input: candiesCount = [7,4,5,3,8], queries = [[0,2,2],[4,2,4],[2,13,1000000000]]
Output: [true,false,true]
Explanation:
1- If you eat 2 candies (type 0) on day 0 and 2 candies (type 0) on day 1, you will eat a candy of type 0 on day 2.
2- You can eat at most 4 candies each day.
If you eat 4 candies every day, you will eat 4 candies (type 0) on day 0 and 4 candies (type 0 and type 1) on day 1.
On day 2, you can only eat 4 candies (type 1 and type 2), so you cannot eat a candy of type 4 on day 2.
3- If you eat 1 candy each day, you will eat a candy of type 2 on day 13.
```
**Example 2:**
```
Input: candiesCount = [5,2,6,4,1], queries = [[3,1,2],[4,10,3],[3,10,100],[4,100,30],[1,3,1]]
Output: [false,true,true,false,false]
```
**Constraints:**
- `1 <= candiesCount.length <= 105`
- `1 <= candiesCount[i] <= 105`
- `1 <= queries.length <= 105`
- `queries[i].length == 3`
- `0 <= favoriteTypei < candiesCount.length`
- `0 <= favoriteDayi <= 109`
- `1 <= dailyCapi <= 109`
## 题目大意
给你一个下标从 0 开始的正整数数组 candiesCount 其中 candiesCount[i] 表示你拥有的第 i 类糖果的数目。同时给你一个二维数组 queries 其中 queries[i] = [favoriteTypei, favoriteDayi, dailyCapi] 。你按照如下规则进行一场游戏:
- 你从第 0 天开始吃糖果。
- 你在吃完 所有 第 i - 1 类糖果之前不能 吃任何一颗第 i 类糖果。
- 在吃完所有糖果之前,你必须每天 至少 吃 一颗 糖果。
请你构建一个布尔型数组 answer 满足 answer.length == queries.length 。answer[i]  true 的条件是在每天吃 不超过 dailyCapi 颗糖果的前提下你可以在第 favoriteDayi 天吃到第 favoriteTypei 类糖果否则 answer[i] 为 false 。注意只要满足上面 3 条规则中的第二条规则你就可以在同一天吃不同类型的糖果。请你返回得到的数组 answer 
## 解题思路
- 每天吃糖个数的下限是 1 颗,上限是 dailyCap。针对每一个 query 查询在第 i 天能否吃到 i 类型的糖果,要想吃到 i 类型的糖果,必须吃完 i-1 类型的糖果。意味着在 [favoriteDayi + 1, (favoriteDayi+1)×dailyCapi] 区间内能否包含一颗第 favoriteTypei 类型的糖果。如果能包含则输出 true不能包含则输出 false。吃的糖果数是累积的所以这里利用前缀和计算出累积吃糖果数所在区间 [sum[favoriteTypei1]+1, sum[favoriteTypei]]。最后判断 query 区间和累积吃糖果数的区间是否有重叠即可。如果重叠即输出 true。
- 判断两个区间是否重合,情况有好几种:内包含,全包含,半包含等等。没有交集的情况比较少,所以可以用排除法。对于区间 [x1, y1] 以及 [x2, y2],它们没有交集当且仅当 x1 > y2 或者 y1 < x2
## 代码
```go
package leetcode
func canEat(candiesCount []int, queries [][]int) []bool {
n := len(candiesCount)
prefixSum := make([]int, n)
prefixSum[0] = candiesCount[0]
for i := 1; i < n; i++ {
prefixSum[i] = prefixSum[i-1] + candiesCount[i]
}
res := make([]bool, len(queries))
for i, q := range queries {
favoriteType, favoriteDay, dailyCap := q[0], q[1], q[2]
x1 := favoriteDay + 1
y1 := (favoriteDay + 1) * dailyCap
x2 := 1
if favoriteType > 0 {
x2 = prefixSum[favoriteType-1] + 1
}
y2 := prefixSum[favoriteType]
res[i] = !(x1 > y2 || y1 < x2)
}
return res
}
```