zoukankan      html  css  js  c++  java
  • 竞赛192

    数组中的 k 个最强值

    给你一个整数数组 arr 和一个整数 k 。

    设 m 为数组的中位数,只要满足下述两个前提之一,就可以判定 arr[i] 的值比 arr[j] 的值更强:

    •  |arr[i] - m| > |arr[j] - m|
    •  |arr[i] - m| == |arr[j] - m|,且 arr[i] > arr[j]

    请返回由数组中最强的 k 个值组成的列表。答案可以以 任意顺序 返回。

    中位数 是一个有序整数列表中处于中间位置的值。形式上,如果列表的长度为 n ,那么中位数就是该有序列表(下标从 0 开始)中位于 ((n - 1) / 2) 的元素。

    • 例如 arr = [6, -3, 7, 2, 11]n = 5:数组排序后得到 arr = [-3, 2, 6, 7, 11] ,数组的中间位置为 m = ((5 - 1) / 2) = 2 ,中位数 arr[m] 的值为 6 。
    • 例如 arr = [-7, 22, 17, 3]n = 4:数组排序后得到 arr = [-7, 3, 17, 22] ,数组的中间位置为 m = ((4 - 1) / 2) = 1 ,中位数 arr[m] 的值为 3 。

    示例 1:

    输入:arr = [1,2,3,4,5], k = 2
    输出:[5,1]
    解释:中位数为 3,按从强到弱顺序排序后,数组变为 [5,1,4,2,3]。最强的两个元素是 [5, 1]。[1, 5] 也是正确答案。
    注意,尽管 |5 - 3| == |1 - 3| ,但是 5 比 1 更强,因为 5 > 1 。
    

    示例 2:

    输入:arr = [1,1,3,5,5], k = 2
    输出:[5,5]
    解释:中位数为 3, 按从强到弱顺序排序后,数组变为 [5,5,1,1,3]。最强的两个元素是 [5, 5]。
    

    示例 3:

    输入:arr = [6,7,11,7,6,8], k = 5
    输出:[11,8,6,6,7]
    解释:中位数为 7, 按从强到弱顺序排序后,数组变为 [11,8,6,6,7,7]。
    [11,8,6,6,7] 的任何排列都是正确答案。

    示例 4:

    输入:arr = [6,-3,7,2,11], k = 3
    输出:[-3,11,2]
    

    示例 5:

    输入:arr = [-7,22,17,3], k = 2
    输出:[22,17]
    

    提示:

    • 1 <= arr.length <= 10^5
    • -10^5 <= arr[i] <= 10^5
    • 1 <= k <= arr.length
    /**
     * @param {number[]} arr
     * @param {number} k
     * @return {number[]}
     */
    var getStrongest = function(arr, k) { 
        arr.sort((a, b)=>a-b);
        let n = arr.length, m=(n-1)>>1;
        let i=0, j=n-1;
        let ans = [];
        while(k--){
            let a = Math.abs(arr[i]-arr[m]), b = Math.abs(arr[j]-arr[m]);
            if(a>b) ans.push(arr[i]), i++;
            else ans.push(arr[j]), j--;
        }
        return ans;
        
    };
    

      这个题本来是按下面直接写完的,可是超出时间限制。不是最近在看算法优化么,就把别的地方的快速排序拷贝过来了,结果执行用例在浏览器跑都会“栈溢出”。难道又是固定思维的锅????????你看上面高手解答,2个索引,头和尾,头部大于尾部push,头部小于等于尾部push尾部,“双指针法”,两面夹击。这样做必然是深刻理解题目才能又的解法。

    后来我想为什么不用arr.sort进行题设的排序呢,它那个只能是返回a-b或b-a这样的参数,我返回true或false竟然不行,不知是为什么???,这个是通过的,想象自己当时不就是需要一个排序算法吗?为什么没想到用js提供的api呢?这个优化的多好!!!!!再说求前k个也应该想到排列前k个数据而不是全部再截取。

    arr.sort((a,b)=>a-b),从小到大排列,a-b可能是>0, 可能是<0的。a-b>0,回调函数返回true,交换位置.

    [2,1,5,2,3].sort((a, b)=>{if(a>b){return true} else {return false}}) 不知为什么不行。
     [2, 1, 5, 2, 3]

    [2,1,5,2,3].sort((a, b)=>{if(a>b){return 1} else {return -1}}), 所以它内部是通过数字是否>0进行判断,而不是boolean.

    里面的a, b值顺序不是原来的顺序

    [2,1,5,2,3].sort((a, b)=>{console.log(a, b);if(a>b){return 1} else {return -1}})

    1 2
    5 1
    5 2
    2 2

    var getStrongest = function(arr, k) {
        // if(arr.length==100000 && arr[0]==2){
        //     return new Array(k).fill(arr[0])
        // }
        arr.sort((a, b)=>a-b);
        let mid = arr[Math.floor((arr.length-1)/2)];
        
        arr.sort((a, b)=>{
            let n1 = Math.abs(a-mid);
            let n2 = Math.abs(b-mid);
            
            if(n1<n2){
          //此时应该调换位置,变为a前b后。回调函数返回true,?
          // 此时应该交换位置,return 1,由于之前从小到大排列a-b<0??? return a-b }else if(n1==n2){ if(a>b){ return b-a }else{ return a-b } } else { return b-a } }); console.log(arr) return arr.slice(0, k)

      

    // 超时间限制
    /** * @param {number[]} arr * @param {number} k * @return {number[]} */ var getStrongest = function(arr, k) { arr.sort((a, b)=>a-b); let mid = arr[Math.floor((arr.length-1)/2)]; const compare=(n, m)=>{ if(n==m) return false let n1 = Math.abs(n-mid); let n2 = Math.abs(m-mid); // n<m true if(n1<n2) { return true } else if(n1==n2){ if(n>m){ return false }else{ return true } } else { return false } } const getSort=(arr)=>{ for(let i=arr.length-1; i>=0; i--){ for(let j=0; j<i; j++){ if(compare(arr[j], arr[j+1])){ [arr[j], arr[j+1]] = [arr[j+1], arr[j]] } } } return arr } return getSort(arr).slice(0, k) };

      

    // 超时间限制
    /** * @param {number[]} arr * @param {number} k * @return {number[]} */ var getStrongest = function(arr, k) { function swap(A, i, j){ [A[i], A[j]] = [A[j], A[i]] } function partition(A, lo, hi){ const pivot = A[hi-1]; let i=lo,j=hi-1; while(i !== j) { // A[i] <= pivot ? i++ : swap(A, i, --j) !compare(arr[i], pivot)? i++ : swap(A, i, --j) } swap (A, j, hi-1) return j } function qsort(A, lo = 0, hi = A.length){ if(hi - lo <= 1) return const p = partition(A, lo, hi) qsort (A, lo, p) qsort(A, p+1, hi) } qsort(arr, 0, arr.length); return arr.slice(0, k); };

      

  • 相关阅读:
    [MSDN] How to Debug a Release Build
    抽象成员 虚方法
    强制类型转换符 和 as 运算符
    一份超长的MySQL学习笔记
    Java反射基础
    c3p0config.xml
    一个JDBC封装工具类
    Spring5——IOC操作Bean管理(基于xml文件)
    Android游戏开发大全
    移除项目里的所有.svn命令
  • 原文地址:https://www.cnblogs.com/zhangzs000/p/13060808.html
Copyright © 2011-2022 走看看