力扣经典题目之912.排序数组(使用希尔排序解决)

今天继续给大家分享一道力扣的做题心得今天这道题目是 912.排序数组

题目链接: 912. 排序数组 - 力扣(LeetCode)

题目: 给你一个整数数组 nums,请你将该数组升序排列。

你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。

示例 1: 输入: nums = [5,2,3,1] 输出:[1,2,3,5]


1,题目分析

此题不难,单纯考察排序,这里我们使用希尔排序来完成此题,希尔排序是一种基于插入排序的改进算法,它通过比较距离一定间隔的元素来工作,然后逐步减小间隔,直到间隔为1时,整个数组基本有序,最后使用插入排序完成最终排序。话不多说,直接上解题代码。

2,解题思路

java 复制代码
class Solution {
    public int[] sortArray(int[] a) {
        int len = a.length;
        int gap = len / 2; // 初始间隔

        while (gap > 0) {
            // 对每个子列表进行插入排序
            for (int i = gap; i < len; i++) {
                int j = i;
                int tmp = a[i];
                // 插入排序,将a[i]插入到前面的有序子列表中
                for (j = i; j >= gap && tmp < a[j - gap]; j -= gap) {
                    a[j] = a[j - gap];
                }
                a[j] = tmp;
            }
            gap /= 2; // 减小间隔
        }
        return a;
    }
}

初始化间隔

  • int gap = len / 2;:初始间隔设置为数组长度的一半。这个间隔用于确定哪些元素将被比较和交换。

外层循环

  • while (gap > 0):只要间隔大于0,就继续进行排序。每次循环结束时,间隔减半,直到间隔为1。

内层循环

  • for (int i = gap; i < len; i++):从间隔gap开始遍历数组。每个元素a[i]将被插入到前面的有序子列表中。
  • int j = i;:初始化一个索引j,用于内层的插入排序。
  • int tmp = a[i];:保存当前元素a[i]的值,用于后续的插入操作。

插入排序

  • for (j = i; j >= gap && tmp < a[j - gap]; j -= gap):从当前元素a[i]开始,向前比较和移动元素,直到找到合适的位置插入tmp。这里的关键是比较tmpa[j - gap],如果tmp小于a[j - gap],则将a[j - gap]向后移动一个间隔。
  • a[j] = tmp;:将tmp插入到正确的位置。

减小间隔

  • gap /= 2;:每次外层循环结束时,间隔减半。这使得算法逐步从宏观的调整(大间隔)过渡到微观的调整(小间隔),最终在间隔为1时进行精细的插入排序。

代码难点

理解希尔排序的原理
  • 希尔排序的关键在于间隔序列的设置。不同的间隔序列会影响算法的性能。在代码中,间隔每次减半,这是一种常见的选择,但不是最优的。例如,可以使用更复杂的间隔序列,如Hibbard序列(1, 3, 7, 15, ...)或Sedgewick序列(1, 5, 19, 41, ...),这些序列可以进一步优化算法的性能。
插入排序的实现
  • 插入排序部分需要仔细处理索引和条件判断。特别是for (j = i; j >= gap && tmp < a[j - gap]; j -= gap)这个循环,需要确保索引j不会越界,并且正确地将tmp插入到合适的位置。
性能优化
  • 希尔排序的性能在很大程度上取决于间隔序列的选择。虽然你的实现已经能够正确排序,但通过选择更优的间隔序列,可以进一步提高算法的效率。

总结

实现了希尔排序算法,能够有效地对数组进行排序。通过逐步减小间隔,算法从宏观调整过渡到微观调整,最终使用插入排序完成排序。理解间隔序列的选择和插入排序的实现是掌握希尔排序的关键。通过选择更优的间隔序列,可以进一步优化算法的性能。

4,总结

感谢大家的阅读,希望这篇解题心得能为大家带来一些收获,我们共同进步!大家的点赞就是我的动力谢谢大家,还有什么更优解或者问题欢迎大家在评论区讨论分享!

相关推荐
程序员buddha9 分钟前
2025年华为OD上机考试真题(Java)——数组连续和
java·开发语言·华为od
_Shirley10 分钟前
Unknown Kotlin JVM target: 21
android·java·jvm·jdk·kotlin·android studio
青灯文案111 分钟前
基于Java 的高性能缓存库 Caffeine 详细介绍
java·spring·缓存
苹果酱056724 分钟前
Golang的分布式系统开发
java·spring boot·毕业设计·layui·课程设计
阿巴资源站28 分钟前
uniapp中修改input里的字体颜色
java·前端·uni-app
小小药31 分钟前
springboot
java·spring boot·后端
还是车万大佬35 分钟前
C语言与ASCII码应用之简单加密
c语言·开发语言·算法
程序猿~厾罗37 分钟前
HTML实战课堂之倒计时页面
java
Leonardo_Fibonacci1 小时前
SpringBoot了解
java·spring boot·后端