leetcode update

This commit is contained in:
gameloader 2024-05-10 18:01:29 +08:00
parent 8b1d373748
commit 9d28315f9b

View File

@ -5348,3 +5348,81 @@ func maximumHappinessSum(happiness []int, k int) int64 {
return int64(result) 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].
![0510L1MMRZ5XYJzh](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0510L1MMRZ5XYJzh.png)
### 题解
保存每个分数的值, 和对应的分子分母, 对对应的分数值排序, 取第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
}
```