• 算法笔记1(对数器、冒泡、选择、插入、递归、归并、小和问题和逆序对问题 )


    1、学习使用对数器

    2、冒泡、选择、插入

    3、递归讲解、归并排序的细节讲解

    4、小和问题和逆序对问题

    对数器的概念和使用
    0, 有一个你想要测的方法a,
    1, 实现一个绝对正确但是复杂度不好的方法b,
    2, 实现一个随机样本产生器
    3, 实现比对的方法
    4, 把方法a和方法b比对很多次来验证方法a是否正确。
    5, 如果有一个样本使得比对出错, 打印样本分析是哪个方法出
    错 6,
    当样本数量很多时比对测试依然正确, 可以确定方法a已经
    正确

     

      1 package basic_class_01;
      2 
      3 import java.util.Arrays;
      4 
      5 public class Code_01_InsertionSort {
      6 
      7     public static void insertionSort(int[] arr) {//
      8         if (arr == null || arr.length < 2) {//判断数组是否为空 或者数组元素小于两个数
      9             return;
     10         }
     11         for (int i = 1; i < arr.length; i++) { //从 0~0 插入排序
     12             for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { //核心条件 : j >= 0 && arr[j] > arr[j + 1] 不越界 前面的数大于后边的数
     13                 swap(arr, j, j + 1);
     14             }
     15         }
     16     }
     17 
     18     public static void swap(int[] arr, int i, int j) {//交换
     19         arr[i] = arr[i] ^ arr[j];
     20         arr[j] = arr[i] ^ arr[j];
     21         arr[i] = arr[i] ^ arr[j];
     22     }
     23 
     24     // for test
     25     public static void comparator(int[] arr) { // 实现一个绝对正确的方法 复杂度不好的方法 
     26         Arrays.sort(arr);
     27     }
     28 
     29     // for test
     30     public static int[] generateRandomArray(int maxSize, int maxValue) { //随机数组发生器 长度 和 大小
     31         int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
     32         for (int i = 0; i < arr.length; i++) {
     33             arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
     34         }
     35         return arr;
     36     }
     37 
     38     // for test
     39     public static int[] copyArray(int[] arr) {
     40         if (arr == null) {
     41             return null;
     42         }
     43         int[] res = new int[arr.length];
     44         for (int i = 0; i < arr.length; i++) {
     45             res[i] = arr[i];
     46         }
     47         return res;
     48     }
     49 
     50     // for test
     51     public static boolean isEqual(int[] arr1, int[] arr2) { // 判断两个数组是否相等
     52         if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { // 一个空 一个不空 返回flase
     53             return false;
     54         }
     55         if (arr1 == null && arr2 == null) {  //都为空返回ture  两个数组一样
     56             return true;
     57         }
     58         if (arr1.length != arr2.length) { //长度不相等 返回flase
     59             return false;
     60         }
     61         for (int i = 0; i < arr1.length; i++) { //数组中的每一个元素  有不相等的 返回flase
     62             if (arr1[i] != arr2[i]) {
     63                 return false;
     64             }
     65         }
     66         return true;  //返回true  两个数组相等
     67     }
     68 
     69     // for test
     70     public static void printArray(int[] arr) { //打印数组
     71         if (arr == null) {
     72             return;
     73         }
     74         for (int i = 0; i < arr.length; i++) {
     75             System.out.print(arr[i] + " ");
     76         }
     77         System.out.println();
     78     }
     79 
     80     // for test
     81     public static void main(String[] args) {
     82         int testTime = 500000;  //次数
     83         int maxSize = 100; //大小
     84         int maxValue = 100; //最大值
     85         boolean succeed = true;
     86         for (int i = 0; i < testTime; i++) {
     87             int[] arr1 = generateRandomArray(maxSize, maxValue); //生成一个随机数组发生器给 arr1
     88             int[] arr2 = copyArray(arr1);  // 把 arr1 的元素拷贝给arr2
     89             insertionSort(arr1); //要测试的方法
     90             comparator(arr2); // 绝对正确的方法
     91             if (!isEqual(arr1, arr2)) { //判断是否相等
     92                 succeed = false;
     93                 break;
     94             }
     95         }
     96         System.out.println(succeed ? "Nice!" : "Fucking fucked!");
     97 
     98         int[] arr = generateRandomArray(maxSize, maxValue);
     99         printArray(arr);
    100         insertionSort(arr);
    101         printArray(arr);
    102     }
    103 
    104 }
     1 package com.aixuexi.contact;
     2 
     3 public class BubbleSort {
     4     public static void main(String[] args) {
     5         int arr[] = new int[] {985,2,6};
     6         //冒泡 O(N*N)
     7         for(int end = arr.length-1; end > 0; end--) {
     8             for(int i = 0; i < end; i++) {
     9                 if(arr[i] > arr[i+1]) {
    10                     int tmp = arr[i];
    11                     arr[i] = arr[i+1];
    12                     arr[i+1] = tmp;
    13                 }
    14             }
    15         }
    16         
    17         //选择  O(N*N)
    18         for(int i = 0; i < arr.length -1; ++i) {
    19             
    20             int Indexmin = i;
    21             
    22             for(int j = i + 1; j < arr.length; ++j) {
    23                 Indexmin = arr[j] < arr[Indexmin] ? j : Indexmin; //返回下表 互换下标
    24             }
    25             
    26             //换数   不是换下标
    27             int tmp = arr[i];
    28             arr[i] = arr[Indexmin];
    29             arr[Indexmin] = tmp;    
    30         }
    31         
    32         
    33         //插入  O(N)
    34         for(int i = 1; i < arr.length; i++) {
    35             for(int j = i - 1; j >= 0 && arr[j] > arr[j+1]; j--) {
    36                 arr[i] = arr[j] ^ arr[j+1];
    37                 arr[j] = arr[j] ^ arr[j+1];
    38                 arr[i] = arr[j] ^ arr[j+1];
    39             }
    40         }
    41         
    42         
    43         System.out.println();
    44         for(int i = 0; i <= arr.length-1; i++) {
    45             System.out.printf("%d ",arr[i]);
    46         }
    47         
    48         
    49     }
    50 }

    2、递归

               https://www.cnblogs.com/yaozhenhua/p/11209343.html

      一个递归行为的例子
      master公式的使用
      T(N) = a*T(N/b) + O(N^d)
      1) log(b,a) > d -> 复杂度为O(N^log(b,a))
      2) log(b,a) = d -> 复杂度为O(N^d * logN)
      3) log(b,a) < d -> 复杂度为O(N^d)
      补充阅读: www.gocalf.com/blog/algorithm-complexity-and-master
      theorem.html

    归并排序的细节讲解

     1 package com.aixuexi.contact;
     2 
     3 public class Mergesort {
     4     
     5     public static void mergeSort(int arr[]) {
     6         if(arr == null || arr.length <= 2) {
     7             return ;
     8         }
     9         mergeSort(arr,0,arr.length-1);
    10     }
    11     public static void mergeSort(int arr[],int L,int R) {
    12         
    13         if(L == R) {
    14             return ;
    15         }
    16         int mid = (L + R ) / 2;
    17         mergeSort(arr,L,mid); // 排序左边
    18         mergeSort(arr,mid+1,R);//排序右边
    19         merge(arr,L, mid, R);
    20     }
    21     public static void merge(int arr[],int L,int mid,int R) {
    22         int arr1[] = new int[R -  L + 1];
    23         int i = 0;
    24         int p1 = L;
    25         int p2 = mid + 1;
    26         while(p1 <= mid && p2 <= R) {
    27             arr1[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
    28         }
    29         
    30         while (p1 <= mid) {
    31             arr1[i++] = arr[p1++];
    32         }
    33         while (p2 <= R) {
    34             arr1[i++] = arr[p2++];
    35         }
    36         for (i = 0; i < arr1.length; i++) {
    37             arr[L + i] = arr1[i];
    38         }
    39         
    40     }
    41     
    42     public static void main(String[] args) {
    43         int arr[] = new int[] {1,4,8,3,7,3,43,43,6,8,87,9,4,67};
    44         mergeSort(arr);
    45         for(int i = 0; i < arr.length; i++) {
    46             System.out.println(arr[i]);
    47         }
    48     }
    49 }

    举例:

    小和问题
    在一个数组中, 每一个数左边比当前数小的数累加起来, 叫做这个数组的小和。 求一个数组
    的小和。
    例子:
    [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 com.aixuexi.contact;
    
    /* 2019/7/16  09点25分
     * 
     * 总结:     1个问题行数   --28 行
     * 注意点     38行
     * 
     * return mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r) + merge(arr, l, mid, r);
     * res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0; //算下标
     */
    
    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); 
    //        mergeSort(arr, l, mid); // 0
    //        mergeSort(arr, mid + 1, r); // 0
    //        int ret = merge(arr, l, mid, r); //ret = 9
            
            return mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r) + merge(arr, l, mid, r);
        }
    
        public static int merge(int[] arr, int l, int m, int r) {
            int[] help = new int[r - l + 1];
            int i = 0;
            int p1 = l;
            int p2 = m + 1;
            int res = 0;
            while (p1 <= m && 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 <= m) {
                help[i++] = arr[p1++];
            }
            while (p2 <= r) {
                help[i++] = arr[p2++];
            }
            for (i = 0; i < help.length; i++) {
                arr[l + i] = help[i];
            }
            return res;
        }
        
        public static void main(String[] args) {
            int arr[] = new int[] {1,3,4,2,5};
            int res = smallSum(arr);
            System.out.println(res);
    //        for(int i = 0; i < arr.length; i++) {
    //            System.out.println(arr[i]);
    //        }
            
        }
    
    }
  • 相关阅读:
    效果超酷的textarea的输入字数限提示
    【设计模式(七)】结构型模式之桥接模式
    【设计模式(六)】适配器模式
    【设计模式(四)】原型模式
    【设计模式(三)】工厂模式
    【设计模式(二)】单例模式
    【设计模式(一)】设计模式概览与六大设计原则
    【算法刷题】无重复字符的最长子串
    【算法刷题】全排列 II
    【算法刷题】LRU缓存模拟
  • 原文地址:https://www.cnblogs.com/yaozhenhua/p/11185151.html
Copyright © 2020-2023  润新知