[ 编码 ] 快速排序:负数放在正数前面

正负数排序问题

题目:

  • 输入一个数组,要求将负数排在正数前面
  • 输入:[ 1,-2,-3,0,7,-6 ]
  • 输出:[-6, -2, -3, 0, 7, 1]

分析:

  • 设置头指针top,从头往后找正数
  • 设置尾指针end,从后往头找负数
 /**
     * 交换算法:设置头指针top,尾指针end
     * top++,end--
     * 若 arr[top] > 0 && arr[end] < 0,则交换
     */
    public static void swap(int[] array){
        int top = 0;
        int end = array.length - 1;
        int tmpt;
        while (top < end){
            //top找到大于0
            while (array[top] < 0 && top < end){
                top++;
            }
            //end找到小于0
            while (array[end] > 0 && top < end){
                end--;
            }
            //交换
            tmpt = array[top];
            array[top] = array[end];
            array[end] = tmpt;

            //若交换的值为0,则跳过,防止输入中含有重复的 0 而出现无限循环
            if (array[top] == 0){
                top++;
            }
            if (array[end] == 0){
                end--;
            }
        }
        System.out.println(Arrays.toString(array));
    }

还未解决两个0问题

  • 时间复杂度:O(n*logn)

三色排序练问题

有一个只由012三种元素构成的整数数组,请使用交换、原地排序而不是使用计数进行排序。给定一个只含0,1,2的整数数组A及它的大小,请返回排序后的数组。保证数组大小小于等于500。
测试样例:[0,1,1,0,2,2],6
返回: [0,0,1,1,2,2]

解析:运用快排的原理。用数字1来处理,在数组左右各维护一个小于区间和大于区间。

public int[] mergeSort(int[] a, int n)
    {
        return doMergeSort(a, n, 0, n - 1);
    }
        public int[] doMergeSort(int[] a, int n, int start, int end)
    {
        int[] res = new int[n];
        if (n <= 1)
        {
            res[0] = a[start];
            return res;
        }
        // n>=2时,对其左右数组进行处理
        int half = n / 2;
        int leftEnd = start + half - 1;
        int rightStart = leftEnd + 1;
        //递归调用本函数,获取有序的左数组以及右数组
        int[] left = doMergeSort(a, half, start, leftEnd);
        int[] right = doMergeSort(a, n - half, rightStart, end);
        // 将左右序列合并
        int k = 0, i = 0, j = 0;
        while (i < half && j < n - half)
        {//由前往后比较两个序列,取较小值填充到res中,取值后该序列往后移动取下一个值比较
            if (left[i] <= right[j])
            {
                res[k++] = left[i++];
            }
            else
            {
                res[k++] = right[j++];
            }
        }
        // 剩余的直接放入
        while (i < half)
        {
            res[k++] = left[i++];
        }
        while (j < n - half)
        {
            res[k++] = right[j++];
        }
        return res;
    }
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值