荷兰国旗问题

问题描述:
     给定一个整数数组,给定一个值K,这个值在原数组中一定存在,要求把数组中小于K的元素放到
     数组的左边,大于K的元素放到数组的右边,等于K的元素放到数组的中间,最终返回一个整数数组,
     其中只有两个值,分别是等于K的数组部分的左右两个下标值。
思路:
   使用两个指针
   一个指针指向最左边,代表着小于给定值的范围索引  less
   另一个指针指向最右边,代表着大于给定值的范围索引 more
   通过i索引循环遍历数组
循环的条件?
  假设是让左边小于目标值的区间来推着等于区朝着大于区的方向走,则循环条件就是 i != more
                情况一:
                  如果当前值小于给定的目标值
                     a.让当前值和less的后一个元素互换位置,
                     b.然后less向右移动一位(相当于将这个小于目标值的元素包在自己的区间里面 ),less ++
                     c.i后移一位
                情况二:
                  如果当前值大于给定的目标值
                     a.让当前值和more的前一个元素互换位置
                     b.然后more向左移动一位,(相当于将这个大于目标值的元素包在自己的区间里面),more --
                     c.i不动,继续下一次比较
                情况三:
                   如果当前值等于目标值
                     a.i++,跳过
/*
    方法的设计:
        参数:数组,起始位置,终止位置,目标值
        返回:等于目标值的一个范围(数组)
     */
    public static int[] netherlandsFlag(int[] arr, int begin, int end, int target) {
        //先判断起始位置和终止位置是否越界
        if (begin > end) {
            //返回无效的索引位置
            return new int[]{-1, -1};
        }
        //如果起始位置和终止位置相等 则就一个值
        if (begin == end) {
            //返回自身索引位置
            return new int[]{begin, end};
        }
        //范围合理,循环排序
        //小于区的索引 从越界位开始
        int less = begin - 1;
        //大于区的索引 从越界位开始
        int more = end + 1;
        //用于移动的索引位置
        int todo = begin;
        //循环条件:todo需要在触及大于区之前停下
        while (todo < more) {
            //情况一:如果当前值小于目标值
            if (arr[todo] < target) {
                //将小于区的后一个值和当前值进行交换,小于区右扩一个位置,todo后移一个位置
                swap(arr, ++less, todo++);
            } else if (arr[todo] == target) {
                //情况二:如果当前值等于目标值
                //索引直接跳过
                todo++;
            } else {
                //情况三:当前值大于目标值
                //将大于区的前一个元素和当前值进行交换,todo索引不动
                swap(arr, --more, todo);
            }
        }
        return new int[]{less + 1, more - 1};
    }

    //用于交换的方法
    private static void swap(int[] arr, int num1, int num2) {
        //使用异或交换方法,数组中的两个值不能相等,否则交换结果为0
        if (num1 != num2) {
            arr[num1] = arr[num1] ^ arr[num2];
            arr[num2] = arr[num1] ^ arr[num2];
            arr[num1] = arr[num1] ^ arr[num2];
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值