zoukankan      html  css  js  c++  java
  • 小和问题 和逆序对问题

    小和问题
    在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组 的小和。
    例子: [1,3,4,2,5] 1左边比1小的数,没有; 3左边比3小的数,1; 4左边比4小的数,1、3; 2左边比2小的数,1; 5左边比5小的数,1、3、4、2; 所以小和为1+1+3+1+1+3+4+2=16
    逆序对问题 在一个数组中,左边的数如果比右边的数大,则折两个数构成一个逆序对,请打印所有逆序 对。

    package my_basic;
    
    public class SmallSum {
        
        public static int smallsum(int[] arr) {
            if (arr==null || arr.length<2) {
                return 0;
            }
            return mergeSort(arr,0,arr.length-1);    
        }
        
        
        public static int mergeSort(int[] arr, int l, int r) {
            if (l == r) {
                return 0;
            }
    //        int mid = l + ((r-l) >> 1);   //防止溢出
            int mid = (l+r)/2;
            return mergeSort(arr, l, mid) + mergeSort(arr, mid+1, r) + merge(arr,l,mid,r);
        }
    
        
        public static int merge(int[] arr, int l, int mid, int r) {
            int res = 0;
            int[] help = new int[r - l + 1];   //help的长度不是一个大的N 而是每次分治 的长度
            int i=0;
            int p1 = l;
            int p2 = mid+1;
            
            while(p1 <= mid && p2 <= r) {
                res += arr[p1] < arr[p2] ? (r-p2+1)*arr[p1] : 0 ;    //核心
                help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++] ;
            }
            while(p1<=mid) {
                help[i++] = arr[p1++];
            }
            while (p2<=r) {
                help[i++] = arr[p2++];
                
            }
            //拷贝到 arr数组
            for (int j = 0; j < help.length; j++) {
                arr[l+j] = help[j];  //这里写错了 掉了 l
            }
            return res;
        }
    
        //对数器  生成随机长度    随机值的数组
        public static int[] generateRamdomArray(int maxSize, int maxValue) {
            int[] array = new int[(int) ((maxSize+1)* Math.random())];
            for (int i = 0; i < array.length; i++) {
                array[i] = (int) ((maxValue+1)* Math.random()) - (int) ((maxValue+1)* Math.random());
            }
            return array;
            
        }
        
        //一个复杂度高但是正确的方法 for 测试另一种方法
        public static int comparator(int[] arr) {
            int res = 0;
            if (arr == null || arr.length < 2 ) {
                return 0;
            }
            for (int i = 1; i < arr.length; i++) {
                for (int j = 0; j < i; j++) {
                    res += (arr[j] < arr[i] ? arr[j] : 0 );
                }
            }
            System.out.println("res:"+res);
            return res;
            
        }
        //判断两个数组是否相等
        public static boolean isEqual(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 < arr2.length; i++) {
                if (arr1[i]!=arr2[i]) {
                    return false;
                }
            }
            return true;
        }
        
        //复制数组
        public static int[] copyArrar(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;
        }
    
        public static void printArray(int[] arr) {
            if (arr == null) {
                return;
            }
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
        
        public static void main(String[] args) {
            int testTime = 5000;
            int maxSize = 10;
            int maxValue = 50;
            boolean flag = true;
            
            int[] arr1 = generateRamdomArray(maxSize, maxValue);
            int[] arr2 = copyArrar(arr1);
            
            printArray(arr1);
            printArray(arr2);
            
            for (int i = 0; i < testTime; i++) {
                if (smallsum(arr1)!= comparator(arr2)) {
                     flag = false;
                     printArray(arr1);
                     printArray(arr2);
                     break;
                }
            }
            System.out.println(flag ? "Nice!" : "Fucking fucked!");
            
        }
    }


    逆序对问题类似:
    package my_basic;
    
    public class ReverseOrder {
        
            public static void reverseOrder(int[] arr) {
                if (arr==null || arr.length<2) {
                    return ;
                }
                 mergeSort(arr,0,arr.length-1);
            }
            
            
            public static int mergeSort(int[] arr, int l, int r) {        
                if (l == r) {
                    return 0;
                }
                int mid = (l+r)/2;
                int k = mergeSort(arr, l, mid)+mergeSort(arr, mid+1, r)+merge(arr,l,mid,r);
                System.out.println("merge总逆序数:"+k);
                return k;
            }
    
            public static int merge(int[] arr, int l, int mid, int r) {
                int merge_res=0;
                int[] help = new int[r - l + 1];   //help的长度不是一个大的N 而是每次分治 的长度
                int i=0;
                int p1 = l;
                int p2 = mid+1;
                
                while(p1 <= mid && p2 <= r) {
                    if ( arr[p2] < arr[p1] ) {    //说明 p2 此时比p1中剩下的元素都小    
                        merge_res += (mid-p1+1);  //核心 
                    }
                    help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++] ;
                }
                while(p1<=mid) {
                    help[i++] = arr[p1++];
                }
                while (p2<=r) {
                    help[i++] = arr[p2++];
                    
                }
                //拷贝到 arr数组
                for (int j = 0; j < help.length; j++) {
                    arr[l+j] = help[j];  //这里写错了 掉了 l
                }
                System.out.println("merge_res:"+merge_res);
                return merge_res;
            }
    
            //对数器  生成随机长度    随机值的数组
            public static int[] generateRamdomArray(int maxSize, int maxValue) {
                int[] array = new int[(int) ((maxSize+1)* Math.random())];
                for (int i = 0; i < array.length; i++) {
                    array[i] = (int) ((maxValue+1)* Math.random()) - (int) ((maxValue+1)* Math.random());
                }
                return array;
                
            }
            
            //一个复杂度高但是正确的方法 for 测试另一种方法
            public static void comparator(int[] arr) {
                int comparator_res=0;
                for (int i = 1; i < arr.length; i++) {
                    for (int j = 0; j < i; j++) {
                        if (arr[j]>arr[i]) {
    //                        System.out.println(arr[j]+","+arr[i]);
                            comparator_res++;
                        }
                    }
                }
                System.out.println("comparator_res:"+ comparator_res);
            }
            //判断两个数组是否相等
            public static boolean isEqual(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 < arr2.length; i++) {
                    if (arr1[i]!=arr2[i]) {
                        return false;
                    }
                }
                return true;
            }
            
            //复制数组
            public static int[] copyArrar(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;
            }
    
            public static void printArray(int[] arr) {
                if (arr == null) {
                    return;
                }
                for (int i = 0; i < arr.length; i++) {
                    System.out.print(arr[i] + " ");
                }
                System.out.println();
            }
            
            public static void main(String[] args) {
                int testTime = 5000;
                int maxSize = 10;
                int maxValue = 50;
                boolean flag = true;
                
                int[] arr1 = generateRamdomArray(maxSize, maxValue);
                int[] arr2 = copyArrar(arr1);
                
                printArray(arr1);
                System.out.println("----------------");
    
                comparator(arr2);
                System.out.println("============");
                reverseOrder(arr1);
                
    
                
            }
        }
    
    
    
     
  • 相关阅读:
    Mac下使用SSH连接远程Linux服务器
    Kafka 中文文档
    计算器如何使用取模功能,调出程序员功能,35171799%15的结果是9
    pm2好用的node进程管理工具,监控进程开机自启动,java进程配置,安装Nodejs环境
    vuejs Mac环境下npm run serve 提示 node_modules/.bin/vue-cli-service: Permission denied问题解决方案
    0day相关信息安全技术
    零基础如何学习Web安全?
    余弦的渗透利器
    知道创宇研发技能表v3.1
    Redis主从复制、哨兵、Cluster三种模式
  • 原文地址:https://www.cnblogs.com/lihuazhu/p/10741634.html
Copyright © 2011-2022 走看看