mirror of
https://gitlab.com/game-loader/hugo.git
synced 2025-04-20 05:52:07 +08:00
leetcode update
This commit is contained in:
parent
8b1d373748
commit
9d28315f9b
@ -5348,3 +5348,81 @@ func maximumHappinessSum(happiness []int, k int) int64 {
|
||||
return int64(result)
|
||||
}
|
||||
```
|
||||
|
||||
## day73 2024-05-10
|
||||
|
||||
### 786. K-th Smallest Prime Fraction
|
||||
|
||||
You are given a sorted integer array arr containing 1 and prime numbers, where all the integers of arr are unique. You are also given an integer k.
|
||||
|
||||
For every i and j where 0 <= i < j < arr.length, we consider the fraction arr[i] / arr[j].
|
||||
|
||||
Return the kth smallest fraction considered. Return your answer as an array of integers of size 2, where answer[0] == arr[i] and answer[1] == arr[j].
|
||||
|
||||

|
||||
|
||||
### 题解
|
||||
|
||||
保存每个分数的值, 和对应的分子分母, 对对应的分数值排序, 取第k小的即可
|
||||
|
||||
### 代码
|
||||
|
||||
```go
|
||||
|
||||
func kthSmallestPrimeFraction(arr []int, k int) []int {
|
||||
type point struct{
|
||||
value float32
|
||||
num []int
|
||||
}
|
||||
points := []point{}
|
||||
length := len(arr)
|
||||
i := 0
|
||||
for index, value := range arr{
|
||||
float32val := float32(value)
|
||||
for i=index+1;i<length;i++{
|
||||
points = append(points, point{float32val/float32(arr[i]),[]int{value, arr[i]}})
|
||||
}
|
||||
}
|
||||
sort.Slice(points, func(i, j int)bool{return points[i].value < points[j].value})
|
||||
return points[k-1].num
|
||||
}
|
||||
```
|
||||
|
||||
### 总结
|
||||
|
||||
看到了一种很有趣的解法, 使用二分法, 每次计算出中间值右侧的分数的个数, 根据与k的相对大小更新中间值. 代码如下, 这种方法比其他许多解法快的多得多, 在最快的平均时长为694ms的情况下竟然只需用时4ms. 这种解法关键在于其通过一开始取中间值为0.5的方式大大减少了需要遍历的分数的数目. 而且没有遍历的分数在后续因为中间值的调整也不会再遍历了, 也就是说每一次遍历的数目都是原本遍历的分数个数的一小部分, 如果数量特别多的情况下可以近似的认为分数的值分布在0-0.5和0.5-1之间的分数个数大致相同. 这样从期望角度讲每次都只需要遍历一般个数的分数, 这样遍历过程总体的时间复杂度为O(nlogn), 并且不需要排序, 最终可以直接返回结果, 因此能有很高的效率.
|
||||
|
||||
```go
|
||||
func kthSmallestPrimeFraction(arr []int, k int) []int {
|
||||
n := len(arr)
|
||||
left := 0.0
|
||||
right := 1.0
|
||||
result := make([]int, 2)
|
||||
|
||||
for left < right {
|
||||
mid := (left + right) / 2
|
||||
count := 0
|
||||
maxFraction := [2]int{0, 1}
|
||||
|
||||
for i, j := 0, 1; i < n-1; i++ {
|
||||
for j < n && float64(arr[i])/float64(arr[j]) > mid {
|
||||
j++
|
||||
}
|
||||
count += n - j
|
||||
if j < n && float64(arr[i])/float64(arr[j]) > float64(maxFraction[0])/float64(maxFraction[1]) {
|
||||
maxFraction = [2]int{arr[i], arr[j]}
|
||||
}
|
||||
}
|
||||
|
||||
if count == k {
|
||||
return maxFraction[:]
|
||||
} else if count < k {
|
||||
left = mid
|
||||
} else {
|
||||
right = mid
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user