将正数移动到数组左边,负数移动到数组右边

题目内容是定一个int数组,将正数移动到数组左边,负数移动到数组右边

经过思考,发现了一种比较简单的实现思路,如下:

	public static void main(String[] args) {
		int[] arr =  {8, 6, 4, -3, 5, -2, -1, 0, 1, -9, 1, -1};
		int index = -1;				   //定义指针
		for (int i=0; i < arr.length; i++) {
			if(arr[i]<0 && index==-1) {//找到最前面的负数
				index = i;
			}			
			if(arr[i]>=0 && index!=-1) {//找到了紧跟其后的正数
				//交换值
				int temp = arr[index];
				arr[index] = arr[i];
				arr[i] = temp;
				
				i = index;				//由于index前面的负数已经与正数交换过,所以将i重置到负数的位置
				index = -1;				//将指针重置后,重复循环操作
			}		
		}		
		System.out.println(Arrays.toString(arr));
		
	}

运行结果如下:

然后还有一种更简单的实现思路,拿出来分好类,再放进去:

	public static void main(String[] args) {
		int[] arr =  {8, 6, 4, -3, 5, -2, -1, 0, 1, -9, 1, -1};
		List<Integer> list1 = new ArrayList<Integer>();//存储正数
		List<Integer> list2 = new ArrayList<Integer>();//存储负数
		for (Integer i : arr) {//遍历数组将数据存到对应的集合中
			if(i>=0) {
				list1.add(i);
			}else {
				list2.add(i);
			}
		}
		for (int i = 0; i < arr.length; i++) {//正数填充到左边,负数填充到右边
			if(i<list1.size()) {
				arr[i] = list1.get(i);
			}else {
				arr[i] = list2.get(i-list1.size());
			}
		}
		System.out.println(Arrays.toString(arr));
	}

运行结果如下:

用list集合取代数组进行操作,将负数移动到末尾:

	public static void main(String[] args) {
		int[] arr =  {8, 6, 4, -3, 5, -2, -1, 0, 1, -9, 1, -1};
		List<Integer> list = new ArrayList<Integer>();
		for (Integer i : arr) { //将数据填充入集合,方便操作
			list.add(i);
		}
		int size = list.size();
		for (int i = 0; i < size; i++) {
			if(list.get(i)<0) {
				list.add(list.remove(i)); //将负数移动到集合尾部
				size--; //由于末位已经是负数了,遍历长度减一
				i--; //由于此处负数移动到了末尾,所以下标需要回退一步
			}
		}
		for (int i = 0; i < list.size(); i++) { //将数据填充到数组中
			arr[i] = list.get(i);
		}
		System.out.println(Arrays.toString(arr));
	}

运行结果如下:

这个是我在网上无意中发现的一种解决思路,不仅快而且巧妙:

	public static void main(String[] args) {
		int[] arr =  {8, 6, 4, -3, 5, -2, -1, 0, 1, -9, 1, -1};	
		int left = 0; //定义指针,从左侧开始
		int right = arr.length-1; // 定义指针,从右侧开始
		while(left<right) {		//当左指针小于右指针时
			if(arr[left]<0 && arr[right]>=0) {//如果左边为负,右边为正,则交换值
				arr[left] = arr[left]+arr[right];
				arr[right] = arr[left]-arr[right];
				arr[left] = arr[left]-arr[right];								
			}
			if(arr[left]>=0) { //如果左数为正,则切换成下一个左数
				left++;
			}
			if(arr[right]<0) { //如果右数为负,则切换成下一个右数
				right--;
			}
		}
		System.out.println(Arrays.toString(arr));
	}

运行结果如下:

朋友通过改进后得到的,单侧指针法,可以说更加巧妙简单吧:

	public static void main(String[] args) {
		int[] arr =  {8, 6, 4, -3, 5, -2, -1, 0, 1, -9, 1, -1};	
		for (int i = 0,j = 0; i < arr.length; i++) {
			if(arr[i]>=0) { //当前值大于等于0,自己与自己交换。或者当j指针指向负数时,与j指针对应的数交换
				int temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp; 
				j++; //大于等于0,指针继续走,遇到负数停下,等待下一个正数然后交换。
			}	
		}
		System.out.println(Arrays.toString(arr));
	}

运行结果如下:

由此引申出一种单侧指针快排的方法:

    
    public static void main(String[] args) {
        int[] arr =  {3, 8, 6, 4, -3, 5, -2, -1, 0, 1, -9, 1, -1, 2};
        quickSort(0,arr.length,arr);
    }

    //思路:使得数组中某数的一边大于自己,一边小于自己,当递归到更小的数组范围时,如果每个更小的数组范围内都是有序的,那么整个数组最终是有序的。
    public static void quickSort(int low, int high, Integer[] arr) {
        if(low >= high) {
            return;
        }
        int j = low;
        int lv = arr[low];
        for (int i = low; i < high; i++) {
            if(arr[i] >= lv) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
                j++;
                System.out.println(Arrays.toString(arr));
            }
        }

        arr[low] = arr[j-1];
        arr[j-1] = lv;
        System.out.println(Arrays.toString(arr));


        quickSort(low,j - 1, arr);
        quickSort(j ,high, arr);
    }


   //while循环替代for
    public static void quickSort(int low, int high, int[] arr) {
        if(low >= high) {
            return;
        }
        int i = low,j = low;
        int lv = arr[low];
        while(i < high) {
            if(arr[i] <= lv) {
                swap(i, j, arr);
                j++;
            }
            i++;
        }
        arr[low] = arr[j-1];
        arr[j-1] = lv;

        quickSort(low,j - 1, arr);
        quickSort(j ,high, arr);
    }
    

最终运行结果如下:

[8, 6, 5, 4, 3, 2, 1, 1, 0, -1, -1, -2, -3, -9]

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值