关于循环后的left和j交换问题

来源:2-9 作业:Select K 问题

qq_PCplayer_0

2020-11-18 15:37:06

# 具体遇到的问题

# 报错信息的截图

# 相关课程内容截图

# 尝试过的解决思路和结果

# 粘贴全部相关代码,切记添加代码注释(请勿截图)

public int[] getLeastNumbers(int[] arr, int k) {

    if (k == 0) {

        return new int[0];

    } else if (arr.length <= k) {

        return arr;

    }

    

    // 原地不断划分数组

    partitionArray(arr, 0, arr.length - 1, k);

    

    // 数组的前 k 个数此时就是最小的 k 个数,将其存入结果

    int[] res = new int[k];

    for (int i = 0; i < k; i++) {

        res[i] = arr[i];

    }

    return res;

}


void partitionArray(int[] arr, int lo, int hi, int k) {

    // 做一次 partition 操作

    int m = partition(arr, lo, hi);

    // 此时数组前 m 个数,就是最小的 m 个数

    if (k == m) {

        // 正好找到最小的 k(m) 个数

        return;

    } else if (k < m) {

        // 最小的 k 个数一定在前 m 个数中,递归划分

        partitionArray(arr, lo, m-1, k);

    } else {

        // 在右侧数组中寻找最小的 k-m 个数

        partitionArray(arr, m+1, hi, k);

    }

}


// partition 函数和快速排序中相同,具体可参考快速排序相关的资料

// 代码参考 Sedgewick 的《算法4》

int partition(int[] a, int lo, int hi) {

    int i = lo;

    int j = hi + 1;

    int v = a[lo];

    while (true) { 

        while (a[++i] < v) {

            if (i == hi) {

                break;

            }

        }

        while (a[--j] > v) {

            if (j == lo) {

                break;

            }

        }


        if (i >= j) {

            break;

        }

        swap(a, i, j);

    }

    swap(a, lo, j);


    // a[lo .. j-1] <= a[j] <= a[j+1 .. hi]

    return j;

}


作者:nettee

链接:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/solution/tu-jie-top-k-wen-ti-de-liang-chong-jie-fa-you-lie-/

来源:力扣(LeetCode)

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。




我想问下 为什么“swap(a, lo, j);”是lo和J交换而不是和i交换 我看快排里面都是和i交换的

写回答

1回答

liuyubobobo

2020-11-18

不要记忆最后应该是和 i 交换还是和 j 交换,而要看具体逻辑是怎样的。i 表示什么 j 表示什么,i 怎么变换 j 怎么变化。同样的一个算法,是可以通过改变变量的定义,写出不一样的具体实现的。


这一点我在下一章讲解二分搜索的时候,举了一个具体的例子,如果你感兴趣,可以先学习一下下一章,尤其是这一小节:https://class.imooc.com/lesson/1583#mid=37748


​我的建议是,如果你认为应该和 i 交换,把程序具体改成和 i 交换,实际用一个小数据运行一遍,看看是否正确?如果不正确,通过单步跟踪的方式,具体的看,程序中的每一个变量,在执行过程中,是如何变化的?和你想象的是否一样?为什么会得到错误的结果?你想的逻辑那一步的时候执行有问题?


这是学习算法非常重要的方式,进步就在这个过程中哦。


加油!:)

0

算法与数据结构

波波老师5年集大成之作,算法与数据结构系统学习,考试、面试、竞赛通用

2611 学习 · 1087 问题

查看课程