• 九度 1534:数组中第K小的数字(二分法变形)


    题目描述:

    给定两个整型数组A和B。我们将A和B中的元素两两相加可以得到数组C。
    譬如A为[1,2],B为[3,4].那么由A和B中的元素两两相加得到的数组C为[4,5,5,6]。
    现在给你数组A和B,求由A和B两两相加得到的数组C中,第K小的数字。

    思路

    1. 多年前第一次搞这道题就没弄出来, 今天是大概记得做法, 不过 failed again, 总结起来, 仍然是没有意识到 int 的特殊性, 即 (int+int)/2 得到的仍然是 int

    2. 涉及到二分查找, 用我以前总结的步骤来做, 非常顺利. 核心就是 mid = target, high = mid-1, 尝试向左. 最后返回的应该是 low

    3. target 没有明确给出, 是通过 ini 的特殊性拼凑出来的

    4. 曾想将两个数组拼成矩阵, 因为 Leetcode 和剑指 offer 上都有类似的矩阵二分查找题目, 但失败了

    代码

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    
    using namespace std;
    
    long long a[100010];
    long long b[100010];
    
    long long search(long long x, long long m, long long n) {
        long long cnt = 0;
        long long j = n-1;
        for(long long i = 0; i < m && j >= 0; i++) {
            if(a[i] + b[j] <= x) {
                cnt += (j+1);
            }else{
                while(j >= 0 && a[i]+b[j] > x) {
                    j--;
                }
                if(j >= 0)
                    cnt += (j+1);
            }
        }
        //cout << "cnt = " << cnt << endl;
        return cnt;
    }
    
    long long doCal(long long m, long long n, long long k) {
        long long low = a[0]+b[0];
        long long high = a[m-1] + b[n-1];
    
        while(low <= high) {
            long long mid = (low+high)>>1;
            long long cnt = search(mid, m, n);
            if(cnt >= k) {
                high = mid -1;
            }else{
                low = mid + 1;
            }
        }
        return low;
    }
    
    int main() {
        long long m, n, k;
        //freopen("testcase.txt", "r", stdin);
        while(scanf("%lld%lld%lld", &m, &n, &k) != EOF) {
            for(long long i = 0; i < m; i ++)
                scanf("%lld", &a[i]);
            for(long long i = 0; i < n; i ++)
                scanf("%lld", &b[i]);
            sort(a, a+m);
            sort(b, b+n);
    
            long long res = doCal(m, n, k);
            printf("%lld
    ", res);
    
        }
    
        return 0;
    }
  • 相关阅读:
    前端开发资料、实用小工具
    冒泡排序法,二分查找法
    数组练习
    一维数组练习题
    for循环输出菱形
    练习题
    课堂练习
    gO语言的安装和环境变量的配置
    PO BO VO DTO POJO DAO 概念及其作用
    BaseServlet
  • 原文地址:https://www.cnblogs.com/xinsheng/p/3579593.html
Copyright © 2020-2023  润新知