zoukankan      html  css  js  c++  java
  • 《算法笔记》1. 复杂度、排序、二分、异或

    1 时间复杂度、空间复杂度、排序、异或运算

    1.1 时间复杂度

    • 常数时间操作:
    1. 算数运算:+ - * /
    2. 位运算:>>(带符号右移动)、 >>>(不带符号右移动) 、 <<、 | 、& 、^

    带符号就是最高位补符号位,不带符号就是最高位补0

    1. 赋值操作:比较,自增,自减操作
    2. 数组寻址等

    总之,执行时间固定的操作都是常数时间的操作。反之执行时间不固定的操作,都不是常数时间的操作

    • 通过基本动作的常数时间,推导时间复杂度

    对于双层循环来说,n(常数)+ (n-1)(常数)+ ... + 2(常数) + 1(常数) => 推导出

    y = an^2 + bn + c
    

    忽略掉低阶项,忽略掉常数项,忽略掉高阶项的系数,得到时间复杂度为n^2

    1.1.1 排序操作

    1.1.1.1 选择排序

    package class01;
    
    import java.util.Arrays;
    
    public class Code01_SelectionSort {
    
    	public static void selectionSort(int[] arr) {
    		if (arr == null || arr.length < 2) {
    			return;
    		}
    		// 0 ~ N-1
    		// 1~n-1
    		// 2
    		for (int i = 0; i < arr.length - 1; i++) { // i ~ N-1
    			// 最小值在哪个位置上  i~n-1
    			int minIndex = i;
    			for (int j = i + 1; j < arr.length; j++) { // i ~ N-1 上找最小值的下标 
    				minIndex = arr[j] < arr[minIndex] ? j : minIndex;
    			}
    			swap(arr, i, minIndex);
    		}
    	}
    
    	public static void swap(int[] arr, int i, int j) {
    		int tmp = arr[i];
    		arr[i] = arr[j];
    		arr[j] = tmp;
    	}
    
    	// for test
    	public static void comparator(int[] arr) {
    		Arrays.sort(arr);
    	}
    
    	// for test
    	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[] 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);
    			selectionSort(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);
    		selectionSort(arr);
    		printArray(arr);
    	}
    
    }
    

    1.1.1.2 冒泡排序

    package class01;
    
    import java.util.Arrays;
    
    public class Code02_BubbleSort {
    
    	public static void bubbleSort(int[] arr) {
    		if (arr == null || arr.length < 2) {
    			return;
    		}
    		// 0 ~ N-1
    		// 0 ~ N-2
    		// 0 ~ N-3
    		for (int e = arr.length - 1; e > 0; e--) { // 0 ~ e
    			for (int i = 0; i < e; i++) {
    				if (arr[i] > arr[i + 1]) {
    					swap(arr, i, i + 1);
    				}
    			}
    		}
    	}
    
    	// 交换arr的i和j位置上的值
    	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);
    			bubbleSort(arr1);
    			comparator(arr2);
    			if (!isEqual(arr1, arr2)) {
    				succeed = false;
    				break;
    			}
    		}
    		System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    
    		int[] arr = generateRandomArray(maxSize, maxValue);
    		printArray(arr);
    		bubbleSort(arr);
    		printArray(arr);
    	}
    
    }
    

    1.1.1.3 插入排序

    package class01;
    
    import java.util.Arrays;
    
    public class Code03_InsertionSort {
    
    	public static void insertionSort(int[] arr) {
    		if (arr == null || arr.length < 2) {
    			return;
    		}
    		// 0~0 有序的
    		// 0~i 想有序
    		for (int i = 1; i < arr.length; i++) { // 0 ~ i 做到有序
    			for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
    				swap(arr, j, j + 1);
    			}
    		}
    	}
    
    	// i和j是一个位置的话,会出错
    	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) {
    		// Math.random() ->  [0,1) 所有的小数,等概率返回一个
    		// Math.random() * N -> [0,N) 所有小数,等概率返回一个
    		// (int)(Math.random() * N) -> [0,N-1] 所有的整数,等概率返回一个
    		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; // 随机数组的长度0~100
    		int maxValue = 100;// 值:-100~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)) {
    				// 打印arr1
    				// 打印arr2
    				succeed = false;
    				break;
    			}
    		}
    		System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    
    		int[] arr = generateRandomArray(maxSize, maxValue);
    		printArray(arr);
    		insertionSort(arr);
    		printArray(arr);
    	}
    
    }
    
    

    插入排序和前面两种排序的不同是在于,插入排序跟数组初始顺序有关,在初始有序的情况下,有可能时间复杂度为O(N),有可能为O(N ^2),但是我们估计时间复杂度要按照最差的情况来估计,所以插入排序的时间复杂度仍然O(N ^2)

    1.2 空间复杂度

    申请有限几个变量,和样本量n没关系,就是空间复杂度O(1),如果要开辟一个空间数组和样本量n是一样大,用来支持我们的算法流程那么O(N)。反之用户就是要实现数组拷贝,我们开辟一个新的n大小数组用来支撑用户的需求,那么仍然是O(1)

    1.3 常数项时间复杂度

    如果两个相同时间复杂度的算法要比较性能,这个时候需要比较单个常数项时间,对能力要求较高,没有意义,不如样本量试验实际测试来比较

    1.4 算法最优解

    我们认为最优解的考虑顺序是,先满足时间复杂度指标,再去使用较少的空间。一般来说,算法题,ACM等不会卡常数项时间

    1.5 常见时间复杂度

    依次从好到坏 O(1) -> O(logN) -> O(N) -> O(N*logN) -> O(N^2) -> O(N^3) ... -> O(N!)

    1.6 算法和数据结构脉络

    1. 知道怎么算的算法
    2. 知道怎么试的算法(递归)

    1.7 认识对数器

    1. 准备你想要测试的方法a
    2. 实现一个复杂度不好,但是容易实现的方法b
    3. 实现一个随机样本产生器
    4. 把方法a和方法b跑相同的随机样本,看看得到的结果是否一样
    5. 如果有一个随机样本使得对比结果不一致,打印样本进行人工干预,改对方法a和方法b
    6. 当样本数量很多,测试对比依然正确,可以确定方法a已经正确

    1.8 认识二分法

    1. 在一个有序数组中,找某个数是否存在

    二分查找值,基于有序数组,算法复杂度为二分了多少次,O(log2N)可以写成O(logN)

    123579

    package class01;
    
    import java.util.Arrays;
    
    public class Code04_BSExist {
    
    	public static boolean exist(int[] sortedArr, int num) {
    		if (sortedArr == null || sortedArr.length == 0) {
    			return false;
    		}
    		int L = 0;
    		int R = sortedArr.length - 1;
    		int mid = 0;
    		// L..R
    		while (L < R) {
    			// mid = (L+R) / 2;
    			// L 10亿  R 18亿
    			// mid = L + (R - L) / 2
    			// N / 2    N >> 1
    			mid = L + ((R - L) >> 1); // mid = (L + R) / 2
    			if (sortedArr[mid] == num) {
    				return true;
    			} else if (sortedArr[mid] > num) {
    				R = mid - 1;
    			} else {
    				L = mid + 1;
    			}
    		}
    		return sortedArr[L] == num;
    	}
    	
    	// for test
    	public static boolean test(int[] sortedArr, int num) {
    		for(int cur : sortedArr) {
    			if(cur == num) {
    				return true;
    			}
    		}
    		return false;
    	}
    	
    	
    	// 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;
    	}
    	
    	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[] arr = generateRandomArray(maxSize, maxValue);
    			Arrays.sort(arr);
    			int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
    			if (test(arr, value) != exist(arr, value)) {
    				succeed = false;
    				break;
    			}
    		}
    		System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    	}
    
    }
    
    1. 在一个有序数组中,找>=某个数最左侧的位置

    122222333578888999999 找大于等于2最左侧的位置

    package class01;
    
    import java.util.Arrays;
    
    public class Code05_BSNearLeft {
    
    	// 在arr上,找满足>=value的最左位置
    	public static int nearestIndex(int[] arr, int value) {
    		int L = 0;
    		int R = arr.length - 1;
    		int index = -1; // 记录最左的对号
    		while (L <= R) {
    			int mid = L + ((R - L) >> 1);
    			if (arr[mid] >= value) {
    				index = mid;
    				R = mid - 1;
    			} else {
    				L = mid + 1;
    			}
    		}
    		return index;
    	}
    
    	// for test
    	public static int test(int[] arr, int value) {
    		for (int i = 0; i < arr.length; i++) {
    			if (arr[i] >= value) {
    				return i;
    			}
    		}
    		return -1;
    	}
    
    	// 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 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 = 500000;
    		int maxSize = 10;
    		int maxValue = 100;
    		boolean succeed = true;
    		for (int i = 0; i < testTime; i++) {
    			int[] arr = generateRandomArray(maxSize, maxValue);
    			Arrays.sort(arr);
    			int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
    			if (test(arr, value) != nearestIndex(arr, value)) {
    				printArray(arr);
    				System.out.println(value);
    				System.out.println(test(arr, value));
    				System.out.println(nearestIndex(arr, value));
    				succeed = false;
    				break;
    			}
    		}
    		System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    	}
    
    }
    
    1. 在一个有序数组中,找<=某个数最右侧的位置
    
    package class01;
    
    import java.util.Arrays;
    
    public class Code05_BSNearRight {
    
    	// 在arr上,找满足<=value的最右位置
    	public static int nearestIndex(int[] arr, int value) {
    		int L = 0;
    		int R = arr.length - 1;
    		int index = -1; // 记录最右的对号
    		while (L <= R) {
    			int mid = L + ((R - L) >> 1);
    			if (arr[mid] <= value) {
    				index = mid;
    				L = mid + 1;
    			} else {
    				R = mid - 1;
    			}
    		}
    		return index;
    	}
    
    	// for test
    	public static int test(int[] arr, int value) {
    		for (int i = arr.length - 1; i >= 0; i--) {
    			if (arr[i] <= value) {
    				return i;
    			}
    		}
    		return -1;
    	}
    
    	// 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 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 = 500000;
    		int maxSize = 10;
    		int maxValue = 100;
    		boolean succeed = true;
    		for (int i = 0; i < testTime; i++) {
    			int[] arr = generateRandomArray(maxSize, maxValue);
    			Arrays.sort(arr);
    			int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
    			if (test(arr, value) != nearestIndex(arr, value)) {
    				printArray(arr);
    				System.out.println(value);
    				System.out.println(test(arr, value));
    				System.out.println(nearestIndex(arr, value));
    				succeed = false;
    				break;
    			}
    		}
    		System.out.println(succeed ? "Nice!" : "Fucking fucked!");
    	}
    
    }
    
    
    1. 局部最小值问题

    无序数组,任意两个相邻的数不相等,返回一个局部最小值

    package class01;
    
    public class Code06_BSAwesome {
    
    	public static int getLessIndex(int[] arr) {
    		if (arr == null || arr.length == 0) {
    			return -1; // no exist
    		}
    		if (arr.length == 1 || arr[0] < arr[1]) {
    			return 0;
    		}
    		if (arr[arr.length - 1] < arr[arr.length - 2]) {
    			return arr.length - 1;
    		}
    		int left = 1;
    		int right = arr.length - 2;
    		int mid = 0;
    		while (left < right) {
    			mid = (left + right) / 2;
    			if (arr[mid] > arr[mid - 1]) {
    				right = mid - 1;
    			} else if (arr[mid] > arr[mid + 1]) {
    				left = mid + 1;
    			} else {
    				return mid;
    			}
    		}
    		return left;
    	}
    
    }
    

    1.9 认识异或运算

    异或运算:相同为0,不同为1

    同或运算:相同为1, 不同为0,不掌握

    上述特别不容易记住,异或运算就记成无进位相加:比如十进制6异或7,就理解为110和111按位不进位相加,得到001

    1. 所以 0^N = N , N^N = 0
    2. 异或运算满足交换律和结合律,所以A异或B异或C = A异或(B异或C) = (A异或C)异或B

    题目一:如何不用额外变量就交换两个数

    a = x b = y两个数交换位置
    
    a = a ^ b # 第一步操作,此时 a = x^y , b=y
    b = a ^ b # 第二步操作,此时 a = x^y , b = x^y^y => b = x^0 => b = x
    a = a ^ b # 第三步操作,此时 a = x^y^x, b = x, a=> x^x^y => a=y
    
    三步操作,实现交换ab的值
    
    
    package class01;
    
    public class Test {
    	
    	public static void main(String[] args) {
    		int a = 6;
    		int b = 6;
    		
    		
    		a = a ^ b;
    		b = a ^ b;
    		a = a ^ b;
    		
    		
    		System.out.println(a);
    		System.out.println(b);
    		
    		
    		
    		
    		int[] arr = {3,1,100};
    		
    		System.out.println(arr[0]);
    		System.out.println(arr[2]);
    		
    		swap(arr, 0, 0);
    		
    		System.out.println(arr[0]);
    		System.out.println(arr[2]);
    		
    		
    		
    	}
    	
    	
    	public static void swap (int[] arr, int i, int j) {
    		// arr[0] = arr[0] ^ arr[0];
    		arr[i]  = arr[i] ^ arr[j];
    		arr[j]  = arr[i] ^ arr[j];
    		arr[i]  = arr[i] ^ arr[j];
    	}
    	
    	
    
    }
    

    注意,如果a和b指向同一块内存,改方法不可行

    题目二:一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数

    [2,2,1,3,2,3,2,1,1] 数组中存在四个2,两个3,三个1,定义一个常量等于0,分别对该数组中的数遍历一遍进行异或,最后,该变量等于多少,那么奇数的值就是多少。因为异或运算满足交换和结合律

    题目三:怎么把一个int类型的数,提取出最右侧的1来

    n与上(n取反加1)即可 => N & ( (~N)+1 )

    题目四:一个数组中有两种不相等的数出现了奇数次,其他数出现了偶数次,怎么找到并打印这两种数

    定义一个常量eor = 0,分别对该数组每个数异或,最终结果为a异或b,其中a和b就是这两个奇数,由于a!=b所以a异或b不等于0,即eor的值某一位上一定为1(有可能不止一个1随便选一个例如第八位),用该位做标记对原有数组的数进行分类,那么a和b由于第八位不相同一定被分开,再定义常量eor' = 0分别对第八位为0的数异或,那么得到的值,就是a和b其中一个,由于之前eor = a异或b,那么在用eor和eor'异或,就是另外一个值。一般来说,随便找一个1我们就找最右侧的那个1,如题目三

    package class01;
    
    public class Code07_EvenTimesOddTimes {
    
    	// arr中,只有一种数,出现奇数次
    	public static void printOddTimesNum1(int[] arr) {
    		int eor = 0;
    		for (int i = 0; i < arr.length; i++) {
    			eor ^= arr[i];
    		}
    		System.out.println(eor);
    	}
    
    	// arr中,有两种数,出现奇数次
    	public static void printOddTimesNum2(int[] arr) {
    		int eor = 0;
    		for (int i = 0; i < arr.length; i++) {
    			eor ^= arr[i];
    		}
    		// eor = a ^ b
    		// eor != 0
    		// eor必然有一个位置上是1
    		// 0110010000
    		// 0000010000
    		int rightOne = eor & (~eor + 1); // 提取出最右的1
    		int onlyOne = 0; // eor'
    		for (int i = 0 ; i < arr.length;i++) {
    			//  arr[i] =  111100011110000
    			// rightOne=  000000000010000
    			if ((arr[i] & rightOne) != 0) {
    				onlyOne ^= arr[i];
    			}
    		}
    		System.out.println(onlyOne + " " + (eor ^ onlyOne));
    	}
    
    	
    	public static int bit1counts(int N) {
    		int count = 0;
    		
    		//   011011010000
    		//   000000010000     1
    		
    		//   011011000000
    		// 
    		
    		
    		
    		while(N != 0) {
    			int rightOne = N & ((~N) + 1);
    			count++;
    			N ^= rightOne;
    			// N -= rightOne
    		}
    		
    		
    		return count;
    		
    	}
    	
    	
    	public static void main(String[] args) {
    		int a = 5;
    		int b = 7;
    
    		a = a ^ b;
    		b = a ^ b;
    		a = a ^ b;
    
    		System.out.println(a);
    		System.out.println(b);
    
    		int[] arr1 = { 3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1 };
    		printOddTimesNum1(arr1);
    
    		int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };
    		printOddTimesNum2(arr2);
    
    	}
    
    }
    
  • 相关阅读:
    Fibonacci数列--矩阵乘法优化
    没有上司的舞会--树形DP
    扩展欧几里德--解的个数
    洛谷 P1284 三角形牧场 题解(背包+海伦公式)
    2017-2018 ACM-ICPC Latin American Regional Programming Contest J
    求1-1e11内的素数个数(HDU 5901 Count primes )
    Educational Codeforces Round 96 (Rated for Div. 2) E. String Reversal 题解(思维+逆序对)
    HHKB Programming Contest 2020 D
    牛客练习赛71 数学考试 题解(dp)
    2019-2020 ICPC Asia Hong Kong Regional Contest J. Junior Mathematician 题解(数位dp)
  • 原文地址:https://www.cnblogs.com/darope/p/13283129.html
Copyright © 2011-2022 走看看