首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2022-01-28:比如{ 5, 3, 1, 4 } 全部数字对是:(5,3)、(5,1)、(5,4)、(3,1)、(3,4)

2022-01-28:比如{ 5, 3, 1, 4 } 全部数字对是:(5,3)、(5,1)、(5,4)、(3,1)、(3,4)

作者头像
福大大架构师每日一题
发布2022-03-04 15:07:26
发布2022-03-04 15:07:26
26200
举报
运行总次数:0

2022-01-28:比如{ 5, 3, 1, 4 }

全部数字对是:(5,3)、(5,1)、(5,4)、(3,1)、(3,4)、(1,4)

数字对的差值绝对值:2、4、1、2、1、3

差值绝对值排序后:1、1、2、2、3、4

给定一个数组arr,和一个正数k

返回arr中所有数字对差值的绝对值,第k小的是多少

arr = { 5, 3, 1, 4 }, k = 4

返回2

答案2022-01-28:

排序+二分+不回退。

时间复杂度:O(log(大-小))*O(N)。

空间复杂度:O(1)。

代码用golang编写。代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
package main

import (
    "fmt"
    "sort"
)

func main() {
    fmt.Println(kthABS2([]int{5, 3, 1, 4}, 4))
}

// 二分 + 不回退
func kthABS2(arr []int, k int) int {
    n := len(arr)
    if n < 2 || k < 1 || k > ((n*(n-1))>>1) {
        return -1
    }
    sort.Ints(arr)
    // 0 ~ 大-小 二分
    // l  ~  r
    left := 0
    right := arr[n-1] - arr[0]
    mid := 0
    rightest := -1
    for left <= right {
        mid = (left + right) / 2
        // 数字对差值的绝对值<=mid的数字对个数,是不是 < k个的!
        if valid(arr, mid, k) {
            rightest = mid
            left = mid + 1
        } else {
            right = mid - 1
        }
    }
    return rightest + 1
}

// 假设arr中的所有数字对,差值绝对值<=limit的个数为x
// 如果 x < k,达标,返回true
// 如果 x >= k,不达标,返回false
func valid(arr []int, limit, k int) bool {
    x := 0
    for l, r := 0, 1; l < len(arr); r = getMax(r, l) {
        for r < len(arr) && arr[r]-arr[l] <= limit {
            r++
        }
        x += r - l - 1
        l++
    }
    return x < k
}

func getMax(a, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

执行结果如下:

[左神java代码](https://github.com/algorithmzuo/coding-for-great-offer/blob/main/src/class48/Code01_MinKthPairMinusABS.java)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档