算法 排序例题

1.1 几乎有序的数组排序,每个元素移动距离不超过K,远小于数组长度

  • o(N) 计数,基数,不知导数据的范围,不考虑
  • o(N^2) 冒泡,选择,与数组中数据顺序无关,插入排序可以
  • o(n*logn) 快排,与原始数据无关,归并,与原始顺序无关
    改进后的堆排序,建立大小为k的堆,进行堆调整,弹出最小值,放在数组首位,再将一个数放进堆中,堆调整,弹出,放在数组第二位。

1.2 判断数组中是否有重复值,必须保证额外空间复杂度为o(1)

  • 没有额外条件,用哈希表实现
  • 先排序,使用不用递归实现的堆排序

1.3 两个有序数组合并,第一个数组空间足够大

从后往前覆盖数组a

1.4 只包含0,1,2的整数数组进行排序,要求使用交换,原地排序,而不是利用计数进行排序

{} 1 1 0 1 2 {}

思路

  • 0区坐标
  • 2区坐标
  • 从右往左遍历
  • 发现是2取得交换后,坐标位置不变,需要再交换一次。
  • 注意,在到达区域2之前停操作,不然会出错。
public class sort {
    public static void main(String[] args) {
        int[] array = new int[]{1,1,2,1,0,0,2,1};
        int length = array.length;
        int flag2 = length;
        int flag0 = -1;
        for (int i = 0; i < length; i++) {
            if (i <= flag2 - 1) {
                if (array[i] == 0) {
                    int mid = 0;
                    mid = array[i];
                    array[i] = array[flag0 + 1];
                    array[flag0 + 1] = mid;
                    flag0++;
                }
                if (array[i] == 2) {
                    int mid = 0;
                    mid = array[i];
                    array[i] = array[flag2 - 1];
                    array[flag2 - 1] = mid;
                    flag2--;
                    if (array[i] == 0) {
                        int mid1 = 0;
                        mid1 = array[i];
                        array[i] = array[flag0 + 1];
                        array[flag0 + 1] = mid1;
                        flag0++;
                    }
                }
            }
        }
        for(int i : array){
            System.out.print(i + " ");
        }
    }
}

1.5 在二维数组行列都排好序的情况下找数

  • 思路观察规律

0 1 2 3
1 2 3 4
1 2 3 5
3 4 5 6
从二维数组的右上角找,如果是M*N的二维数组,则最优解可能是O(M+N),比如说找2,从第一行开始,走到2,发现后面3比2大,则第四列不可能,从第三列继续,往下,发现比2大,不可能,跳过,一步步找规律

1.6 需要排序的最短子数组长度

[1,2,3,5,2,4,3,5]
最优解:时间复杂度为o(N),额外复杂度为o(1)

思路:

  • 从左往右找中间值,即左边的数比他大,右边的数比他小的数,记为max,往右找,直到比他大的数;
  • 从右往左找中间值,即左边的数比他小,右边的数比他大的数,记为max,往左找,直到比他小的数;
public class sort {
    public static void main(String[] args) {
        int[] array = new int[]{1,2,3,4,32,43,53,5,7,8,9};
        int flag0 = 0;
        int flag1 = 0;
        for (int i = 1; i < array.length - 1; i++) {
            if(array[i - 1] < array[i] && array[i] > array[i + 1]){
                flag0 = i;
                break;
            }
        }
        for (int i = 1; i < array.length  - 1; i++) {
            if(array[array.length - i - 1] > array[array.length -i] && array[array.length -i] <  array[array.length -i - 2]){
                flag1 = array.length -i;
                break;
            }
        }
        for (int i = flag0; i < array.length; i++) {
            if (array[i] > array[flag0] || i == array.length - 1){
                flag0 = i;
                break;
            }
        }
        for(int i = flag1; i > 0; i--){
            if(array[i] < array[flag1] || i == 0){
                flag1 = i;
                break;
            }
        }
        System.out.println(flag0 - flag1);
    }
}

1.7 给定一个整形数组arr,返回排序之后,相邻两数的最大差值

最优解:最优解时间复杂度是o(N),需要的辅助空间是o(N)

使用桶排序,找到最大值和最小值,桶的个数等于最大数据的个数,桶代表的值是(最大值-最小值)/桶的个数,最大值单独在一个桶

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值