mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2026-03-13 10:02:05 +08:00
添加 problem 378
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
)
|
||||
|
||||
// 解法一 二分搜索
|
||||
func kthSmallest378(matrix [][]int, k int) int {
|
||||
m, n, low := len(matrix), len(matrix[0]), matrix[0][0]
|
||||
high := matrix[m-1][n-1] + 1
|
||||
for low < high {
|
||||
mid := low + (high-low)>>1
|
||||
// 如果 count 比 k 小,在大值的那一半继续二分搜索
|
||||
if counterKthSmall(m, n, mid, matrix) >= k {
|
||||
high = mid
|
||||
} else {
|
||||
low = mid + 1
|
||||
}
|
||||
}
|
||||
return low
|
||||
}
|
||||
|
||||
func counterKthSmall(m, n, mid int, matrix [][]int) int {
|
||||
count, j := 0, n-1
|
||||
// 每次循环统计比 mid 值小的元素个数
|
||||
for i := 0; i < m; i++ {
|
||||
// 遍历每行中比 mid 小的元素的个数
|
||||
for j >= 0 && mid < matrix[i][j] {
|
||||
j--
|
||||
}
|
||||
count += j + 1
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// 解法二 优先队列
|
||||
func kthSmallest3781(matrix [][]int, k int) int {
|
||||
if len(matrix) == 0 || len(matrix[0]) == 0 {
|
||||
return 0
|
||||
}
|
||||
pq := &pq{data: make([]interface{}, k)}
|
||||
heap.Init(pq)
|
||||
for i := 0; i < len(matrix); i++ {
|
||||
for j := 0; j < len(matrix[0]); j++ {
|
||||
if pq.Len() < k {
|
||||
heap.Push(pq, matrix[i][j])
|
||||
} else if matrix[i][j] < pq.Head().(int) {
|
||||
heap.Pop(pq)
|
||||
heap.Push(pq, matrix[i][j])
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return heap.Pop(pq).(int)
|
||||
}
|
||||
|
||||
type pq struct {
|
||||
data []interface{}
|
||||
len int
|
||||
}
|
||||
|
||||
func (p *pq) Len() int {
|
||||
return p.len
|
||||
}
|
||||
|
||||
func (p *pq) Less(a, b int) bool {
|
||||
return p.data[a].(int) > p.data[b].(int)
|
||||
}
|
||||
|
||||
func (p *pq) Swap(a, b int) {
|
||||
p.data[a], p.data[b] = p.data[b], p.data[a]
|
||||
}
|
||||
|
||||
func (p *pq) Push(o interface{}) {
|
||||
p.data[p.len] = o
|
||||
p.len++
|
||||
}
|
||||
|
||||
func (p *pq) Head() interface{} {
|
||||
return p.data[0]
|
||||
}
|
||||
|
||||
func (p *pq) Pop() interface{} {
|
||||
p.len--
|
||||
return p.data[p.len]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question378 struct {
|
||||
para378
|
||||
ans378
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para378 struct {
|
||||
matrix [][]int
|
||||
k int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans378 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem378(t *testing.T) {
|
||||
|
||||
qs := []question378{
|
||||
|
||||
question378{
|
||||
para378{[][]int{[]int{1, 5, 9}, []int{10, 11, 13}, []int{12, 13, 15}}, 8},
|
||||
ans378{13},
|
||||
},
|
||||
|
||||
question378{
|
||||
para378{[][]int{[]int{1, 5, 7}, []int{11, 12, 13}, []int{12, 13, 15}}, 3},
|
||||
ans378{9},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 378------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans378, q.para378
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, kthSmallest378(p.matrix, p.k))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
||||
40
Algorithms/378. Kth Smallest Element in a Sorted Matrix/README.md
Executable file
40
Algorithms/378. Kth Smallest Element in a Sorted Matrix/README.md
Executable file
@@ -0,0 +1,40 @@
|
||||
# [378. Kth Smallest Element in a Sorted Matrix](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.
|
||||
|
||||
Note that it is the kth smallest element in the sorted order, not the kth distinct element.
|
||||
|
||||
**Example:**
|
||||
|
||||
matrix = [
|
||||
[ 1, 5, 9],
|
||||
[10, 11, 13],
|
||||
[12, 13, 15]
|
||||
],
|
||||
k = 8,
|
||||
|
||||
return 13.
|
||||
|
||||
**Note:**You may assume k is always valid, 1 ≤ k ≤ n2.
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。请注意,它是排序后的第 k 小元素,而不是第 k 个元素。
|
||||
|
||||
|
||||
说明:
|
||||
你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
|
||||
- 给出一个行有序,列有序的矩阵(并非是按照下标有序的),要求找出这个矩阵中第 K 小的元素。注意找的第 K 小元素指的不是 k 个不同的元素,可能存在相同的元素。
|
||||
- 最容易想到的就解法是优先队列。依次把矩阵中的元素推入到优先队列中。维护一个最小堆,一旦优先队列里面的元素有 k 个了,就算找到结果了。
|
||||
- 这一题最优解法是二分搜索。那搜索的空间是什么呢?根据题意,可以知道,矩阵左上角的那个元素是最小的,右下角的元素是最大的。即矩阵第一个元素确定了下界,矩阵的最后一个元素确定了上界。在这个解空间里面二分搜索所有值,找到第 K 小的元素。判断是否找到的条件是,在矩阵中比 mid 小的元素个数等于 K。不断的逼近 low,使得 low == high 的时候,就是找到了第 K 小的元素了。(因为题目中说了,一定会存在第 K 小元素,所以二分搜索到一个元素的时候,一定会得出结果)。
|
||||
|
||||

|
||||
Reference in New Issue
Block a user