算法基础入门——选择、冒泡、插入、二分、异或运算

public class code01 { /** * 选择排序 * 遍历一轮选择最小的,每轮确定一个数的位置 * 时间复杂度O(N^2),额外空间复杂度O(1) */ public static void selectionSort(int[] arr) { if (arr == null || arr.length < 2){ return; } for (int i = 0; i < arr.length - 1; i++) { int minIndex = i; for (int j = i + 1; j <arr.length; j++) { minIndex = arr[j] < arr[minIndex] ? j : minIndex; } // 如果minIndex等于i,就是其本身就不用交换,如果使用异或交换就会变为0 if (minIndex != i) { swap(arr, i, minIndex); } } } /** * 冒泡排序 * 遍历一轮,确定一个数的位置,相邻比较 * 时间复杂度O(N^2),额外空间复杂度O(1) */ public static void bubbleSort(int[] arr) { if (arr == null || arr.length < 2) { return; } for (int k = arr.length - 1; k > 0; k--) { for (int i = 0; i < k; i++) { if (arr[i] > arr[i+1]) { swap(arr, i, i + 1); } } } } /** * 插入排序 * 左边有序,右边无序 * 时间复杂度O(N^2),额外空间复杂度O(1) */ 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]; } /** * 在有序数组中,使用二分法查找某数是否存在 * @return */ public static boolean BSExist(int[] arr, int num) { if (arr == null && arr.length == 0) { return false; } int left = 0; int right = arr.length -1; int mid = 0; while (left < right) { // mid = left + ((right - left) >> 1); mid = (left + right) / 2; if (arr[mid] == num) { return true; } else if (arr[mid] > num) { right = mid -1; } else { left = mid + 1; } } // return sortedArr[left] == num; return false; } /** * 在有序数组中,使用二分查找>=某个数的最左侧位置 * @return */ public static int BSNearLeft(int[] arr, int num) { if (arr == null && arr.length == 0) { return 0; } int index = -1; int left = 0; int right = arr.length -1; int mid; while (left < right) { mid = left + ((right - left) >> 1); if (arr[mid] >= num) { index = mid; right = mid -1; } else { left = mid + 1; } } return index; } /** * 一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数? * 运用异或运算,出现偶数次的数异或后等于0,最后异或的结果就是出现奇数次的数 * 0^N == N * N^N == 0 * @param arr */ public static void printOddTimesNum1(int[] arr) { int a = 0; for (int b :arr) { a = a ^ b; } System.out.println(a); } /** * 一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到这两个数 * @param arr */ public static void printOddTimesNum2(int[] arr) { int a = 0; int one = 0; // 获取到2个数异或的值 for (int b :arr) { a = a ^ b; } // 获取2个数异或的值的最右边的1,与上(取反+1) int rightOne = a & (~a + 1); // 将数组分为2类,独自异或,可以得到一个出现奇数次的数 for (int b :arr) { if ((b & rightOne) != 0) { one ^= b; } } System.out.println(one +" "+ (one ^ a)); } /** * 用递归方法找一个数组中的最大值 * @param arr * @param left * @param right * @return */ public static int getMax(int[] arr, int left, int right) { if (left == right) { return arr[left]; } int mid = left + ((right - left) >> 1); int leftMax = getMax(arr, left, mid); int rightMax = getMax(arr, mid + 1, right); return Math.max(leftMax,rightMax); } /** * 局部最小值问题 * 局部最小值的概念。arr长度为1时,arr[0]是局部最小。arr的长度为N(N > 1)时,如果arr[0]<arr[1],那么arr[0]是局部最小; * 如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小;如果0<i<N-1,既有arr[i]<arr[i-1],又有arr[i]<arr[i+1],那么arr[i]是局部最小。 * 给定无序数组arr,已知arr中任意两个相邻的数都不相等。写一个函数,只需返回arr中任意一个局部最小出现的位置即可。 * @param arr * @return */ public static int getLessIndex(int[] arr) { if (arr == null || arr.length == 0) { return -1; } 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 - left) >> 1); // 注意这里判断条件 // 上升趋势,抛弃右边,保持先降后升的趋势 if (arr [mid] > arr[mid - 1]) { right = mid - 1; // 下降趋势,抛弃左边 保持先降后升趋势 } else if (arr[mid] > arr[mid + 1]) { left = mid + 1; } else { // 找到局部最小了 return mid; } } // 剩余一个 return left; } public static void main(String[] args) { int[] arr1 = {212,1561,451,15415,451,12,4511,45315,5616,4565}; // 选择排序 selectionSort(arr1); for (int i = 0; i < arr1.length; i++) { System.out.println(arr1[i]); } int[] arr2 = {212,1561,451,15415,451,12,4511,45315,5616,4565}; // 冒泡排序 bubbleSort(arr2); for (int i = 0; i < arr2.length; i++) { System.out.println(arr2[i]); } int[] arr3 = {212,1561,451,15415,451,12,4511,45315,5616,4565}; // 插入排序 insertionSort(arr3); for (int i = 0; i < arr2.length; i++) { System.out.println(arr3[i]); } // 二分查找某数 boolean b = BSExist(arr3, 451); System.out.println(b); // 二分查找>=某数最左侧位置 int i = BSNearLeft(arr3, 452); System.out.println(i); // 一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数 int[] arr4 = { 3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1 }; printOddTimesNum1(arr4); // 一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到这两个数 int[] arr5 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 }; printOddTimesNum2(arr5); // 递归获取数组最大值 int max = getMax(arr3, 0, arr3.length - 1); System.out.println(max); // 局部最小值问题 int[] arr6 = {6, 5, 7, 3, 4, 6, 7, 8}; for (int j = 0; j != arr6.length; j++) { System.out.print(arr6[j] + " "); } System.out.println(); int index = getLessIndex(arr6); System.out.println("index: " + index + ", value: " + arr6[index]); } }

 


__EOF__

本文作者北漂的尘埃
本文链接https://www.cnblogs.com/shizhe99/p/15969272.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   北漂的尘埃  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示