時間複雑度再学習


時間複雑度再学習


1.認識時間の複雑さ


定数時間の操作:1つの操作がデータ量と関係がなければ、毎回一定時間内に完了する操作を定数操作と呼ぶ.時間複雑度はアルゴリズムフローにおける定数動作数の指標である.O(big Oと読む)で表されることが多い.具体的には、定数動作数の式では、高次項、低次項、高次項の係数が不要であれば、残りの部分をf(N)と記すと、時間複雑度はO(f(N))となる.アルゴリズムの流れの良し悪しを評価し,まず時間の複雑さの指標を見てから,異なるデータサンプルの下での実際の運転時間,すなわち定数項時間を分析する.
時間の複雑さはデータ規模にも関係しており,2つのアルゴリズムがあれば優劣が見られ,サンプル量も考慮する必要がある.
データフローが決定されたため、挿入ソートはデータ規模に関係し、好ましくはo(N)であり、すべて順序がある.

2.対数器の概念と使用


0、測定したい方法がありますa.
1,絶対的に正しいが複雑度が悪い方法bを実現する.
2、ランダムサンプル発生器を実現する.
3,ペアリングを実現する方法.
4,方法aと方法bを何度も比較して方法aが正しいかどうかを検証する.
5.比較エラーが発生したサンプルがある場合、印刷サンプルはどの方法でエラーが発生したかを分析する.
6.サンプルの数が多い場合、比較テストは依然として正確であり、方法aが正しいと判断できる.
package basic_class_01;
import java.util.Arrays;
public class Code_00_BubbleSort{
	public static void bubblesort(int []arr) {
		if(arr==null||arr.length<2) {
			return;
		}
		for(int e=arr.length-1;e>0;e--) {
			for(int i=0;i<e;i++) {
				if(arr[i]>arr[i+1]) {
					swap(arr,i,i+1);
				}
			}
		}
	}
	public 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];
	//unsigned int a=60;  //0011 1100
	//	                unsigned int b=13;  //0000 1101
	//	                a=a^b;              //a=a^b=0011 0001
	//	                b=a^b;              //b=a^b=0011 1100     b1=(a^b)^b
	//	                a=a^b;              //a=a^b=0000 1101     a1=(a^b)^((a^b)^b
		    
	}
	//for test
	public static void comparator(int[] arr) {
		Arrays.sort(arr);
	}
	//for test
	public static int[] generateRandomArray(int maxSize,int maxValue) {
		//Math.random()->double[0,1);
		//(int)((size+1)*Math.random())	—>[0,size]  
		//size=6;size+1=7;
		//Math.random()->[0,1)*7->[0,7)double
		//double->int[0,6]->int
		//           
	   int [] arr=new int[(int)((maxSize+1)*Math.random())];
	   for(int i=0;i<arr.length;i++) {
		   arr[i]=(int)((maxValue+1)*Math.random())-(int)(maxValue*Math.random());
	   }
	return arr;
}
//for test
	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;
	}
	//for test
	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<arr1.length;i++) {
		if(arr1[i]!=arr2[i]){
			return false;
		}
	}
	return true;
}//for test
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();
}
//for test
public static void main(String[] args) {
	int testTime=500000;
	int maxSize=10;
	int maxValue=100;
	boolean succeed=true;
	for(int i=0;i<testTime;i++) {
		int [] arr1=generateRandomArray(maxSize,maxValue);
		int[] arr2=copyArray(arr1);
		bubblesort(arr1);
		comparator(arr2);
		if(!isEqual(arr1,arr2)) {
			succeed=false;
			break;
		}
	}
	System.out.println(succeed?"nice":"Fucking");
	int[] arr=generateRandomArray(maxSize,maxValue);
	      printArray(arr);
	      bubblesort(arr);
	      printArray(arr);
}
}
	
	

3.再帰行為と再帰行為の時間複雑度の推定を分析する


再帰的な行動の例
再帰関数は、システムがスタックを圧縮し、サブプロシージャを呼び出すときにスタックを圧縮し、その後、サブプロシージャが値を返し、スタックを弾き、現場を復元し、任意の再帰動作を非再帰動作に変更することができます.
マスター式の使用T(N)=a*T(N/b)+O(N^d)(分割されたサブ問題の規模は毎回同じ)
例えば、T(n)=T(n/5)+T(2/3 n)+o(n^2)はmaster式では使用できません
T(N)サンプル量はNの時間的複雑度であり,aはサブプロセスの発生回数を表し,N/bはサブプロセスのサンプル量を表す.
  • log(b,a)>d->複雑度O(N^log(b,a))
  • log(b,a)=d->複雑度O(N^d*logN)
  • log(b,a)複雑度O(N^d)補足読書:www.gocalf.com/blog/algorithm-complexity-and-mastertheorem.html

  • 4.集計ソート


    T(n)=2T(n/2)+o(n)->o(n*logn)
    package basic_class_01;
    
    import java.util.Arrays;
    
    public class Code_05_MergeSort {
    public static void mergeSort(int[] arr) {
    	if (arr == null || arr.length < 2) {
    		return;
    	}
    	mergeSort(arr, 0, arr.length - 1);
    }
    
    public static void mergeSort(int[] arr, int l, int r) {
    	if (l == r) {
    		return;
    	}
    	int mid = l + ((r - l) >> 1);
    	mergeSort(arr, l, mid);
    	mergeSort(arr, mid + 1, r);
    	merge(arr, l, mid, r);
    }
    
    public static void 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;
    	while (p1 <= m && p2 <= r) {
    		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];
    	}
    }
    
    // for test
    public static void comparator(int[] arr) {
    	Arrays.sort(arr);
    }
    
    // for test
    public static int[] generateRandomArray(int maxSize, int maxValue) {
    	int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
    	for (int i = 0; i < arr.length; i++) {
    		arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
    	}
    	return arr;
    }
    
    // for test
    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;
    }
    
    // for test
    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 < arr1.length; i++) {
    		if (arr1[i] != arr2[i]) {
    			return false;
    		}
    	}
    	return true;
    }
    
    // for test
    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();
    }
    
    // for test
    public static void main(String[] args) {
    	int testTime = 500000;
    	int maxSize = 100;
    	int maxValue = 100;
    	boolean succeed = true;
    	for (int i = 0; i < testTime; i++) {
    		int[] arr1 = generateRandomArray(maxSize, maxValue);
    		int[] arr2 = copyArray(arr1);
    		mergeSort(arr1);
    		comparator(arr2);
    		if (!isEqual(arr1, arr2)) {
    			succeed = false;
    			printArray(arr1);
    			printArray(arr2);
    			break;
    		}
    	}
    	System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    
    	int[] arr = generateRandomArray(maxSize, maxValue);
    	printArray(arr);
    	mergeSort(arr);
    	printArray(arr);
    
    }
    }
    

    5.小和問題と逆順対問題


    小和問題と逆順序問題小和問題は1つの配列の中で、各数の左側が現在の数より小さい数を累積して、この配列の小和と呼ばれます.1つの配列の小和を求めます.例:[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+3+4+2=16
    逆順序対問題
    1つの配列で、左の数が右の数より大きい場合は、2つの数を折って逆のペアを構成し、すべての逆のペアを印刷します.
    package basic_class_01;
    
    import java.util.Arrays;
    
    public class Code_01_InsertionSort {
    public static void insertionSort(int[] arr) {
    	if (arr == null || arr.length < 2) {
    		return;
    	}
    	for (int i = 1; i < arr.length; i++) {
    		for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
    			swap(arr, j, j + 1);
    		}
    	}
    }
    
    public 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];
    }
    
    // for test
    public static void comparator(int[] arr) {
    	Arrays.sort(arr);
    }
    
    // for test
    public static int[] generateRandomArray(int maxSize, int maxValue) {
    	int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
    	for (int i = 0; i < arr.length; i++) {
    		arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
    	}
    	return arr;
    }
    
    // for test
    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;
    }
    
    // for test
    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 < arr1.length; i++) {
    		if (arr1[i] != arr2[i]) {
    			return false;
    		}
    	}
    	return true;
    }
    
    // for test
    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();
    }
    
    // for test
    public static void main(String[] args) {
    	int testTime = 500000;
    	int maxSize = 100;
    	int maxValue = 100;
    	boolean succeed = true;
    	for (int i = 0; i < testTime; i++) {
    		int[] arr1 = generateRandomArray(maxSize, maxValue);
    		int[] arr2 = copyArray(arr1);
    		insertionSort(arr1);
    		comparator(arr2);
    		if (!isEqual(arr1, arr2)) {
    			succeed = false;
    			break;
    		}
    	}
    	System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    
    	int[] arr = generateRandomArray(maxSize, maxValue);
    	printArray(arr);
    	insertionSort(arr);
    	printArray(arr);
    }
    }