Add solution 417、916

This commit is contained in:
YDZ
2021-03-27 02:31:31 +08:00
parent 1781d4e7a5
commit 427b25d4b7
22 changed files with 689 additions and 82 deletions

View File

@ -0,0 +1,45 @@
package leetcode
import "math"
func pacificAtlantic(matrix [][]int) [][]int {
if len(matrix) == 0 || len(matrix[0]) == 0 {
return nil
}
row, col, res := len(matrix), len(matrix[0]), make([][]int, 0)
pacific, atlantic := make([][]bool, row), make([][]bool, row)
for i := 0; i < row; i++ {
pacific[i] = make([]bool, col)
atlantic[i] = make([]bool, col)
}
for i := 0; i < row; i++ {
dfs(matrix, i, 0, &pacific, math.MinInt32)
dfs(matrix, i, col-1, &atlantic, math.MinInt32)
}
for j := 0; j < col; j++ {
dfs(matrix, 0, j, &pacific, math.MinInt32)
dfs(matrix, row-1, j, &atlantic, math.MinInt32)
}
for i := 0; i < row; i++ {
for j := 0; j < col; j++ {
if atlantic[i][j] && pacific[i][j] {
res = append(res, []int{i, j})
}
}
}
return res
}
func dfs(matrix [][]int, row, col int, visited *[][]bool, height int) {
if row < 0 || row >= len(matrix) || col < 0 || col >= len(matrix[0]) {
return
}
if (*visited)[row][col] || matrix[row][col] < height {
return
}
(*visited)[row][col] = true
dfs(matrix, row+1, col, visited, matrix[row][col])
dfs(matrix, row-1, col, visited, matrix[row][col])
dfs(matrix, row, col+1, visited, matrix[row][col])
dfs(matrix, row, col-1, visited, matrix[row][col])
}

View File

@ -0,0 +1,56 @@
package leetcode
import (
"fmt"
"testing"
)
type question417 struct {
para417
ans417
}
// para 是参数
// one 代表第一个参数
type para417 struct {
matrix [][]int
}
// ans 是答案
// one 代表第一个答案
type ans417 struct {
one [][]int
}
func Test_Problem417(t *testing.T) {
qs := []question417{
{
para417{[][]int{
{1, 2, 2, 3, 5},
{3, 2, 3, 4, 4},
{2, 4, 5, 3, 1},
{6, 7, 1, 4, 5},
{5, 1, 1, 2, 4},
}},
ans417{[][]int{
{0, 4},
{1, 3},
{1, 4},
{2, 2},
{3, 0},
{3, 1},
{4, 0},
}},
},
}
fmt.Printf("------------------------Leetcode Problem 417------------------------\n")
for _, q := range qs {
_, p := q.ans417, q.para417
fmt.Printf("【input】:%v 【output】:%v\n", p, pacificAtlantic(p.matrix))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,92 @@
# [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/)
## 题目
Given an `m x n` matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left and top edges of the matrix and the "Atlantic ocean" touches the right and bottom edges.
Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower.
Find the list of grid coordinates where water can flow to both the Pacific and Atlantic ocean.
**Note:**
1. The order of returned grid coordinates does not matter.
2. Both m and n are less than 150.
**Example:**
```
Given the following 5x5 matrix:
Pacific ~ ~ ~ ~ ~
~ 1 2 2 3 (5) *
~ 3 2 3 (4) (4) *
~ 2 4 (5) 3 1 *
~ (6) (7) 1 4 5 *
~ (5) 1 1 2 4 *
* * * * * Atlantic
Return:
[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix).
```
## 题目大意
给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。请找出那些水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标。
## 解题思路
- 暴力解法,利用 DFS 把二维数据按照行优先搜索一遍,分别标记出太平洋和大西洋水流能到达的位置。再按照列优先搜索一遍,标记出太平洋和大西洋水流能到达的位置。最后两者都能到达的坐标即为所求。
## 代码
```go
package leetcode
import "math"
func pacificAtlantic(matrix [][]int) [][]int {
if len(matrix) == 0 || len(matrix[0]) == 0 {
return nil
}
row, col, res := len(matrix), len(matrix[0]), make([][]int, 0)
pacific, atlantic := make([][]bool, row), make([][]bool, row)
for i := 0; i < row; i++ {
pacific[i] = make([]bool, col)
atlantic[i] = make([]bool, col)
}
for i := 0; i < row; i++ {
dfs(matrix, i, 0, &pacific, math.MinInt32)
dfs(matrix, i, col-1, &atlantic, math.MinInt32)
}
for j := 0; j < col; j++ {
dfs(matrix, 0, j, &pacific, math.MinInt32)
dfs(matrix, row-1, j, &atlantic, math.MinInt32)
}
for i := 0; i < row; i++ {
for j := 0; j < col; j++ {
if atlantic[i][j] && pacific[i][j] {
res = append(res, []int{i, j})
}
}
}
return res
}
func dfs(matrix [][]int, row, col int, visited *[][]bool, height int) {
if row < 0 || row >= len(matrix) || col < 0 || col >= len(matrix[0]) {
return
}
if (*visited)[row][col] || matrix[row][col] < height {
return
}
(*visited)[row][col] = true
dfs(matrix, row+1, col, visited, matrix[row][col])
dfs(matrix, row-1, col, visited, matrix[row][col])
dfs(matrix, row, col+1, visited, matrix[row][col])
dfs(matrix, row, col-1, visited, matrix[row][col])
}
```

View File

@ -0,0 +1,36 @@
package leetcode
func wordSubsets(A []string, B []string) []string {
var counter [26]int
for _, b := range B {
var m [26]int
for _, c := range b {
j := c - 'a'
m[j]++
}
for i := 0; i < 26; i++ {
if m[i] > counter[i] {
counter[i] = m[i]
}
}
}
var res []string
for _, a := range A {
var m [26]int
for _, c := range a {
j := c - 'a'
m[j]++
}
ok := true
for i := 0; i < 26; i++ {
if m[i] < counter[i] {
ok = false
break
}
}
if ok {
res = append(res, a)
}
}
return res
}

View File

@ -0,0 +1,63 @@
package leetcode
import (
"fmt"
"testing"
)
type question916 struct {
para916
ans916
}
// para 是参数
// one 代表第一个参数
type para916 struct {
A []string
B []string
}
// ans 是答案
// one 代表第一个答案
type ans916 struct {
one []string
}
func Test_Problem916(t *testing.T) {
qs := []question916{
{
para916{[]string{"amazon", "apple", "facebook", "google", "leetcode"}, []string{"e", "o"}},
ans916{[]string{"facebook", "google", "leetcode"}},
},
{
para916{[]string{"amazon", "apple", "facebook", "google", "leetcode"}, []string{"l", "e"}},
ans916{[]string{"apple", "google", "leetcode"}},
},
{
para916{[]string{"amazon", "apple", "facebook", "google", "leetcode"}, []string{"e", "oo"}},
ans916{[]string{"facebook", "google"}},
},
{
para916{[]string{"amazon", "apple", "facebook", "google", "leetcode"}, []string{"lo", "eo"}},
ans916{[]string{"google", "leetcode"}},
},
{
para916{[]string{"amazon", "apple", "facebook", "google", "leetcode"}, []string{"ec", "oc", "ceo"}},
ans916{[]string{"facebook", "leetcode"}},
},
}
fmt.Printf("------------------------Leetcode Problem 916------------------------\n")
for _, q := range qs {
_, p := q.ans916, q.para916
fmt.Printf("【input】:%v 【output】:%v\n", p, wordSubsets(p.A, p.B))
}
fmt.Printf("\n\n\n")
}

View File

@ -0,0 +1,103 @@
# [916. Word Subsets](https://leetcode.com/problems/word-subsets/)
## 题目
We are given two arrays `A` and `B` of words.  Each word is a string of lowercase letters.
Now, say that word `b` is a subset of word `a` ****if every letter in `b` occurs in `a`, **including multiplicity**.  For example, `"wrr"` is a subset of `"warrior"`, but is not a subset of `"world"`.
Now say a word `a` from `A` is *universal* if for every `b` in `B`, `b` is a subset of `a`.
Return a list of all universal words in `A`.  You can return the words in any order.
**Example 1:**
```
Input:A = ["amazon","apple","facebook","google","leetcode"], B = ["e","o"]
Output:["facebook","google","leetcode"]
```
**Example 2:**
```
Input:A = ["amazon","apple","facebook","google","leetcode"], B = ["l","e"]
Output:["apple","google","leetcode"]
```
**Example 3:**
```
Input:A = ["amazon","apple","facebook","google","leetcode"], B = ["e","oo"]
Output:["facebook","google"]
```
**Example 4:**
```
Input:A = ["amazon","apple","facebook","google","leetcode"], B = ["lo","eo"]
Output:["google","leetcode"]
```
**Example 5:**
```
Input:A = ["amazon","apple","facebook","google","leetcode"], B = ["ec","oc","ceo"]
Output:["facebook","leetcode"]
```
**Note:**
1. `1 <= A.length, B.length <= 10000`
2. `1 <= A[i].length, B[i].length <= 10`
3. `A[i]` and `B[i]` consist only of lowercase letters.
4. All words in `A[i]` are unique: there isn't `i != j` with `A[i] == A[j]`.
## 题目大意
我们给出两个单词数组 A  B。每个单词都是一串小写字母。现在如果 b 中的每个字母都出现在 a 中,包括重复出现的字母,那么称单词 b 是单词 a 的子集。 例如“wrr” 是 “warrior” 的子集,但不是 “world” 的子集。如果对 B 中的每一个单词 bb 都是 a 的子集那么我们称 A 中的单词 a 是通用的。你可以按任意顺序以列表形式返回 A 中所有的通用单词。
## 解题思路
- 简单题。先统计出 B 数组中单词每个字母的频次,再在 A 数组中依次判断每个单词是否超过了这个频次,如果超过了即输出。
## 代码
```go
package leetcode
func wordSubsets(A []string, B []string) []string {
var counter [26]int
for _, b := range B {
var m [26]int
for _, c := range b {
j := c - 'a'
m[j]++
}
for i := 0; i < 26; i++ {
if m[i] > counter[i] {
counter[i] = m[i]
}
}
}
var res []string
for _, a := range A {
var m [26]int
for _, c := range a {
j := c - 'a'
m[j]++
}
ok := true
for i := 0; i < 26; i++ {
if m[i] < counter[i] {
ok = false
break
}
}
if ok {
res = append(res, a)
}
}
return res
}
```