mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-06 09:23:19 +08:00
Add solution 0097、0523、0525、1465、1744
This commit is contained in:
35
leetcode/0097.Interleaving-String/97. Interleaving String.go
Normal file
35
leetcode/0097.Interleaving-String/97. Interleaving String.go
Normal 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
|
||||
}
|
||||
}
|
@ -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")
|
||||
}
|
104
leetcode/0097.Interleaving-String/README.md
Normal file
104
leetcode/0097.Interleaving-String/README.md
Normal 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:**
|
||||
|
||||

|
||||
|
||||
```
|
||||
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
|
||||
}
|
||||
}
|
||||
```
|
@ -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
|
||||
}
|
@ -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")
|
||||
}
|
75
leetcode/0523.Continuous-Subarray-Sum/README.md
Normal file
75
leetcode/0523.Continuous-Subarray-Sum/README.md
Normal 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
|
||||
}
|
||||
```
|
27
leetcode/0525.Contiguous-Array/525. Contiguous Array.go
Normal file
27
leetcode/0525.Contiguous-Array/525. Contiguous Array.go
Normal 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
|
||||
}
|
47
leetcode/0525.Contiguous-Array/525. Contiguous Array_test.go
Normal file
47
leetcode/0525.Contiguous-Array/525. Contiguous Array_test.go
Normal 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")
|
||||
}
|
67
leetcode/0525.Contiguous-Array/README.md
Normal file
67
leetcode/0525.Contiguous-Array/README.md
Normal 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
|
||||
}
|
||||
```
|
@ -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)
|
||||
}
|
@ -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")
|
||||
}
|
@ -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:**
|
||||
|
||||

|
||||
|
||||
```
|
||||
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:**
|
||||
|
||||

|
||||
|
||||
```
|
||||
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 条边。
|
||||
|
||||

|
||||
|
||||
## 代码
|
||||
|
||||
```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)
|
||||
}
|
||||
```
|
@ -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
|
||||
}
|
@ -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")
|
||||
}
|
@ -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[favoriteTypei−1]+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
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user