荷兰国旗问题

题目一

给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。
要求额外空间复杂度O(1),时间复杂度O(n)。

分析:遍历数组,只要比num小的,往左排,比num大的,跳过本次操作,这样看来,我们只需要交换满足条件的元素便可以实现题目的要求了。首先我们先建立一个在数组边界外的指针。数组从L至R进行遍历,那么我们的指针当前的位置为index = L-1,在遍历过程中和给定条件进行比较,如满足条件,则交换位置,且index向右移动指针。

public class SortArray {

    public static void sort(int[]arr,int num) {
        if(arr == null || arr.length<2) {
            return;
        }
        int index = -1;  //遍历数组从0开始,那么当前指针的左边界就是-1;
        for(int i=0;i<arr.length;i++) {
            if(arr[i]<=num) {
                swap(arr, ++index, i);  //满足条件交换位置,且index向右移动
            }else {
                continue;
            }
        }
    }
    //交换两个数
    public static void swap(int[] arr,int i,int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    public static void main(String[]args) {
        int []arr  = {2,1,8,5,3,9,7,4,10};
        int num = 6;
        sort(arr, num);
        System.out.println(Arrays.toString(arr));
    }
}

题目二

给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数组的中间,大于num的数放在数组的右边。
要求额外空间复杂度O(1),时间复杂度O(n)

这道题和上述的题目有些相似,唯一不同的是加了个等于num放中间这个条件,其实如果你理解了上述的题目的含义,这道题也不难理解了。解这道题需要将数组划分为3部分,即小于num、等于num、大于num,这样一来我们建立三个索引,分别是左边界的,当前位置索引,右边界的索引,通过移动索引并交换位置即可得到答案。

import java.util.Arrays;

public class QuickSort {
    public static int[] partition(int[] arr,int L,int R,int num){
        int less = L - 1;  //存放小于num数的下标
        int more = R + 1;  //存放大于num数的下标
        int cur = L;
        while(cur<more){
            if(arr[cur]<num) {
                swap(arr, ++less, cur++);    //发现小于num的数,将其与数组左边的小于num部分最右边位置的值进行交换,并移动当前下标
            }else if(arr[cur] > num){   
                swap(arr,--more,cur);       //发现大于num的数,将其放在数组右边的大于num部分最左边的值进行交换,当然不能保证置换过来的值是否依然大于或小于num,所以cur并不移动
            }else{
                cur++;
            }
        }
        return new int[] {less+1,more-1};
    }
    public static void swap(int[] arr,int i ,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    public static void main(String[] args){
        int[] arr = {23,4,2,7,42,8,32,7,8,10,45,63,21};
        int num = 21;
        partition(arr,0,arr.length-1,num);
        System.out.println(Arrays.toString(arr));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值