zoukankan      html  css  js  c++  java
  • 算法路漫漫(三) 荷兰国旗

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

    /**
     * 给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,
     *  大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)
     */
    @Slf4j
    public class Alg008_SeparateArr {
    
    
        @Test
        public void test(){
            for(int i=0;i<5000;i++){
                int[] arr  = generateArr();
                int[] vals = separate(arr, 0);    
                log.info("vals:{}", vals);
            }
        }
    
    
        private int[] separate(int[] arr, int target){
            if(arr.length <2){
                return arr ;
            }
            int l =0;
            for(int i=0;i<arr.length;i++){
               if(arr[i] < target){
                    swap(arr,l++,i);
               } 
            }
            return arr;
    
        }
    
    
        public static void swap(int[] arr, int i, int j) {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    
    
        private int[] generateArr(){
            return new Random().ints(-100, 100).distinct().limit(20).toArray();
     
        }
        
    }

    解题思路: 借助一个辅助变量L下标为0, 遍历数组 比较小于sum的值,与L交换,同时L++

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

    /**
     * 给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,
     *      大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)
     */
    @Slf4j
    public class Alg009_NetherlandsFlag {
    
    
        @Test
        public void test(){
            for(int i=0;i<5000;i++){
                int[] arr  = generateArr();
                log.info("result:{}", change(arr, 0, arr.length-1, 0));
            }
        }
    
        // push the L close to R
        public int[] change(int[] arr, int L,int R,int target){
            int l = L-1;
            int r = R+1;
            while(L < r){
                if(arr[L] < target){
                    swap(arr,++l,L++);
                } else if(arr[L] > target){
                    swap(arr, --r,L);
                } else {
                    L++;
                }
            }
            return arr;
        }
    
        public static void swap(int[] arr, int i, int j) {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    
    
        private int[] generateArr(){
            return new Random().ints(-100, 100).distinct().limit(20).toArray();
     
        }
        
    }

    解题思路: 给数组规定左边界和右边界,以及移动的指针i, 一共有三种比较

    1. arr[i] < num, i和左边界的下一位交换,同时左边界右扩一位,i++

    2. arr[i] == num, i++

    3. arr[i] > num, i和右边界的前一位交换,同时右边界左扩一位,i原地不动

  • 相关阅读:
    php 后端跨域请求
    IIS服务器文件跨域问题(几乎可以解决大多数跨域问题)
    JavaScript中的execCommand
    [原创] 利用前端+php批量生成html文件,传入新文本,输出新的html文件
    javascript 生成 uuid
    zabbix安装 检测环境 PHP bcmath off
    mysql中间件-amoeba
    MySQL备份
    ELK日志分析
    SAMBA配置文件详解
  • 原文地址:https://www.cnblogs.com/hlkawa/p/14942911.html
Copyright © 2011-2022 走看看