【知识积累】荷兰国旗问题2:给定一个数组arr,和一个整数num。请把小于num的数放在数组左边,等于num的数放在中间,大于num的数放在数组的右边。要求时间复杂度O(N),额外空间复杂度(1)

package com.example.demo.algorithm.D004;

/**
 * @Description :
 * 题目:
 * 给定一个数组arr,和一个整数num。请把小于num的数放在数组左边,等于num的数放在中间,大于num的数放在数组的右边。
 * 要求时间复杂度O(N),额外空间复杂度(1)
 *
 * partition流程:
 * 1)将整个数组左边划分为小于区域,下标初始值为-1,右边花费为大于区域,下标初始值为r+1
 * 2)当i位置的数小于num时,当前数arr[i]与小于区域下一个数交换,小于区右扩,i++
 * 3) 当i位置的数大于num时,当前数arr[i]与大于区域上一个数交换,大于区左扩,i原地不变(因为此时i位置的数没有看过)
 * 4)当i位置的数等于num时,i++
 *
 * [5,3,7,2,3,4,1] i=0 a=-1 b=7 num=3(a:左边界  b:右边界)
 *  0 1 2 3 4 5 6
 * 5 > 3  arr[0] swap arr[6] i=0 a=-1 b=6
 *
 * [1,3,7,2,3,4,5]
 *  0 1 2 3 4 5 6
 * 1 < 3 arr[0] swap arr[0] i=1 a=0 b=6
 *
 * [1,3,7,2,3,4,5]
 *  0 1 2 3 4 5 6
 *  3 = 3 i=2 a=0 b=6
 *
 * [1,3,7,2,3,4,5]
 *  0 1 2 3 4 5 6
 * 7 > 3 arr[2] swap arr[5] i=2, a=0, b=5
 *
 * [1,3,4,2,3,7,5]
 *  0 1 2 3 4 5 6
 * 4 > 3 arr[2] swap arr[4] i=2 a=0 b=4
 *
 * [1,3,3,2,4,7,5]
 *  0 1 2 3 4 5 6
 * 3 == 3 i=3 a=0 b=4
 *
 * [1,3,3,2,4,7,5]
 *  0 1 2 3 4 5 6
 *  2 < 3 arr[3] swap arr[1] i=4 a=1 b=4
 *
 * [1,2,3,3,4,7,5]
 *  0 1 2 3 4 5 6
 *    a     b
 * 小于3的在左边,等于3的在中间,大于3的在右边
 *
 * @Author : Darren
 * @Date : 2021 年 02 月 25 日 20:31:54
 * @since : 1.0
 */
public class J002_Partition {

    public static void main(String[] args) {
        int[] arr = {5,3,7,2,3,4,1};
        int[] partition = partition(arr, 0, arr.length - 1, 3);
        printArray(arr);
        printArray(partition);
    }

    /**
     * 给定一个数partition
     * @param arr
     * @param l
     * @param r
     * @param num
     * @return
     */
    public static int[] partition(int[] arr, int l, int r, int num){
        if (l > r){
            return new int[]{-1,-1};
        }
        if (l == r){
            return new int[]{l,r};
        }
        //左边界
        int lessEqual = l-1;
        //右边界
        int moreEqual = r+1;
        int index = l;
        while (index < moreEqual){
            // 当i位置的数小于num时,当前数arr[i]与小于区域下一个数交换,小于区右扩,i++
            // 当i位置的数大于num时,当前数arr[i]与大于区域上一个数交换,大于区左扩,i不变
            // 当i位置的数等于num时,i++
            if (arr[index] < num){
                swap(arr, index++, ++lessEqual);
            }else if(arr[index] > num){
                swap(arr, index, --moreEqual);
            }else{
                index++;
            }
        }
        return new int[]{lessEqual,moreEqual};
    }

    private static void swap(int[] arr, int i, int j) {
        /*arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];*/
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    /**
     * 生成一个随机数组
     * @param maxSize
     * @param maxValue
     * @return
     */
    public static int[] generateRandomArray(int maxSize, int maxValue){
        //Math.random() [0,1)
        //Math.random() * N [0,N)
        //(int)(Math.random() * N) [0,N-1]
        int[] arrays = new int[(int) ((maxSize+1) * Math.random())];
        for (int i = 0; i < arrays.length; i++) {
            arrays[i] = (int) ((maxValue+1) * Math.random()) - (int)(maxValue * Math.random());
        }
        return arrays;
    }

    /**
     * 打印数组
     * @param arrays
     */
    public static void printArray(int[] arrays){
        if (arrays == null){
            return;
        }
        for (int i = 0; i < arrays.length; i++) {
            System.out.print(arrays[i] + " ");
        }
        System.out.println();
    }

    /**
     * 复制数组
     */
    public static int[] copyArray(int[] arr){
        if (arr == null){
            return null;
        }
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    /**
     * 判断两个数组是否相等
     * @param arr1
     * @param arr2
     * @return
     */
    public static boolean isArrayEqual(int[] arr1, int[] arr2){
        if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)){
            return false;
        }

        if (arr1 == null && arr2 == null){
            return true;
        }

        if (arr1.length != arr2.length){
            return false;
        }

        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]){
                return false;
            }
        }
        return true;
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果您想要从一个整数数组中找出小于给定整数m的最大,可以使用以下步骤: 1. 对数组进行排序,使得数组中的按升序排列。 2. 从前往后遍历数组,找到第一个小于m的即为所求。 例如,对于给定数组[5, 10, 15, 20]和字13,可以按以下步骤操作: 1. 对数组进行排序,得到[5, 10, 15, 20]。 2. 从前往后遍历数组,发现5小于13,因此返回5。 如果您想使用代码实现这个功能,可以使用以下Python代码: ``` def find_max(arr, m): arr.sort() # 对数组进行排序 for num in arr: # 遍历数组 if num < m: # 如果小于m,则返回该字 return num return -1 # 如果没有找到小于m的字,则返回-1 ``` 希望这些信息对您有帮助。 ### 回答2: 假设给定的正整数数组arr,长度为n。我们可以通过以下步骤找到小于m的最大: 1. 初始化变量max_num为0,用于保存小于m的最大。 2. 遍历数组arr中的每个元素num: - 如果num小于m且大于max_num,则更新max_numnum。 3. 返回max_num作为结果。 以下是一个具体的示例代码实现: ```python def find_max_num(arr, m): max_num = 0 for num in arr: if num < m and num > max_num: max_num = num return max_num # 测试样例 arr = [10, 20, 30, 40, 50] m = 35 result = find_max_num(arr, m) print(result) # 输出为30 ``` 在该示例中,给定的正整数数组为[10, 20, 30, 40, 50],m为35。我们通过遍历数组中的元素,找到小于35的最大为30。因此,程序输出结果为30。 这个算法时间复杂度为O(n),其中n是数组的长度。 ### 回答3: 首先,我们可以对给定的正整数数组进行排序,将数组中的字按照从小到大的顺序排列。 然后,我们从数组的最后一个字开始,将其与m进行比较。如果该小于m,则说明找到了小于m的最大,直接返回该字。 如果该大于等于m,则继续向前遍历数组,直到找到一个小于m的字或者遍历到数组的第一个字为止。 如果遍历到数组的第一个字仍然大于等于m,则说明数组中所有的字都大于等于m,此时无法找到小于m的最大,返回-1或者其他特定的标识。 综上所述,我们可以编写如下的代码来实现该功能: ``` def findMaxNum(nums, m): nums.sort() # 对数组进行排序 for i in range(len(nums)-1, -1, -1): if nums[i] < m: # 找到小于m的最大 return nums[i] return -1 # 数组中所有字都大于等于m nums = [1, 3, 5, 7, 9] m = 6 result = findMaxNum(nums, m) print(result) # 输出:5 ``` 在这个例子中,给定的正整数数组为[1, 3, 5, 7, 9],m为6。经过排序后,数组变为[1, 3, 5, 7, 9]。遍历数组后发现,最后一个小于6的字是5,因此返回5作为结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值