力扣经典题目之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,总结

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

相关推荐
在努力的前端小白2 小时前
Spring Boot 敏感词过滤组件实现:基于DFA算法的高效敏感词检测与替换
java·数据库·spring boot·文本处理·敏感词过滤·dfa算法·组件开发
Coovally AI模型快速验证4 小时前
农田扫描提速37%!基于检测置信度的无人机“智能抽查”路径规划,Coovally一键加速模型落地
深度学习·算法·yolo·计算机视觉·transformer·无人机
pusue_the_sun4 小时前
数据结构:二叉树oj练习
c语言·数据结构·算法·二叉树
一叶飘零_sweeeet5 小时前
从繁琐到优雅:Java Lambda 表达式全解析与实战指南
java·lambda·java8
RaymondZhao345 小时前
【全面推导】策略梯度算法:公式、偏差方差与进化
人工智能·深度学习·算法·机器学习·chatgpt
艾伦~耶格尔5 小时前
【集合框架LinkedList底层添加元素机制】
java·开发语言·学习·面试
zhangfeng11335 小时前
DBSCAN算法详解和参数优化,基于密度的空间聚类算法,特别擅长处理不规则形状的聚类和噪声数据
算法·机器学习·聚类
一只叫煤球的猫6 小时前
🕰 一个案例带你彻底搞懂延迟双删
java·后端·面试
最初的↘那颗心6 小时前
Flink Stream API 源码走读 - print()
java·大数据·hadoop·flink·实时计算
圣保罗的大教堂6 小时前
leetcode 2348. 全 0 子数组的数目 中等
leetcode