zoukankan      html  css  js  c++  java
  • 数据结构与算法基础01—— 常见基本排序、二分法与异或运算

    常见基本排序

    选择排序
    在这里插入图片描述

    基本思路:从第一位开始标记,每次选出最小数字与标记位交换

    代码实现:

        private static void selectSort(int[] arr) {
            if(arr == null || arr.length < 2){
                return;
            }
            for (int i = 0; i < arr.length-1; i++) {
                int index = i;
                for (int j = i + 1; j < arr.length; j++) {
                    if(arr[j] < arr[index]){
                        index = j;
                    }
                }
                swap(arr, i ,index);
            }
        }
    View Code

    冒泡排序
    在这里插入图片描述

    基本思路:每次比较相邻两个数大小,每次循环选出当轮最大/小数字,每次循环次数环比减一

    代码实现:

        private static void bubbleSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            for (int end = arr.length-1; end >0; end--) {
                for (int start = 0; start < end; start++) {
                    if(arr[start]>arr[start+1]){
                        swap(arr, start, start+1);
                    }
                }
            }
        }
    View Code

    插入排序

    基本思路:保证前面有序的情况下,依次把后面数字插入到指定位置继续保证有序

    代码实现:

        private static void insertionSort(int[] arr) {
            if (arr == null || arr.length < 2) {
                return;
            }
            for (int i = 1; i < arr.length; i++) {
                for (int j = i; j > 0 && arr[j]<arr[j-1]; j--) {
                    swap(arr,j,j-1);
                }
            }
        }
    View Code

    二分法

    基本思路:根据左右边界计算中间位置,中间值和目标值比较,如果中间值小于目标值,左边界等于中间位置+1,如果中间值大于目标值,右边界等于中间位置-1。

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

        private static boolean isExist(int[] arr, int num) {
            if(arr == null || arr.length <2){
                return false;
            }
            int L = 0;
            int R = arr.length-1;
            int mid = 0;
            while (L < R){
                mid = L + ((R-L) >> 1);
                if(arr[mid] == num){
                    return true;
                }else if(arr[mid] < num){
                    L = mid + 1;
                }else{
                    R = mid - 1;
                }
            }
            return arr[L] == num;
        }
    View Code

    在一个有序数组中,找>=某个数最左侧的位置

        private static int leftmostPosition(int[] arr, int num) {
            int L = 0;
            int R = arr.length-1;
            int mid = 0;
            int index = -1;
            while (L <= R){
                mid = L + ((R-L) >> 1);
                if(arr[mid] >= num){
                    index = mid;
                    R = mid - 1;
                }else{
                    L = mid + 1;
                }
            }
            return index;
        }
    View Code

    在一个有序数组中,找<=某个数最右侧的位置

        private static int rightmostPosition(int[] arr, int num) {
            int L = 0;
            int R = arr.length-1;
            int mid = 0;
            int index = -1;
            while (L <= R){
                mid = L + ((R-L) >> 1);
                if(arr[mid] <= num){
                    index = mid;
                    L = mid + 1;
                }else{
                    R = mid - 1;
                }
            }
            return index;
        }
    View Code

    相邻两数不等,局部最小值问题

        private static int localMinimum(int[] arr){
            if(arr == null || arr.length<=1){
                return -1;
            }
            if(arr[0] < arr[1]){
                return 0;
            }
            if(arr[arr.length - 1] < arr[arr.length - 2]){
                return arr.length - 1;
            }
            int L = 1;
            int R = arr.length - 2;
            int mid = 0;
            while (L < R){
                mid = L + ((R - L) >> 1);
                if(arr[mid] > arr[mid-1]){
                    R = mid - 1;
                }else if(arr[mid] > arr[mid+1]){
                    L = mid + 1;
                }else{
                    return mid;
                }
            }
            return -1;
        }
    View Code

    异或运算

    基本规则:相同则0,不同则1

    不用额外变量交换两个数

        private static void swap(int[] arr, int a, int b){
            arr[a] = arr[a] ^ arr[b];
            arr[b] = arr[a] ^ arr[b];
            arr[a] = arr[a] ^ arr[b];
        }
    View Code

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

        private static int getNum(int[] arr){
            if(arr == null || 0 == arr.length){
                return -1;
            }
            int num = 0;
            for (int i = 0; i < arr.length; i++) {
                num ^= arr[i];
            }
            return num;
        }
    View Code

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

        private static void printNums(int[] arr){
            int num = 0;
            for (int i = 0; i < arr.length; i++) {
                num ^= arr[i]; // 最终结果是两种数:a^b
            }
            // a^b不等于0,所以在某个位置,一个数是0,一个数是1
            // 找出最右位置的1,然后取该位置为0的数字进行异或就可以找出其中一个数
            int farRightOne = num & ((~num)+1);
    
            int onlyOne = 0;
            for (int i = 0; i < arr.length; i++) {
                if((arr[i] & farRightOne) != 0){
                    onlyOne ^= arr[i];
                }
            }
            System.out.println(onlyOne + " ^ " + (num ^ onlyOne));
        }
    View Code

    数出二进制1的个数

        private static int getNumberOfOne(int num) {
            int count = 0;
            while (num != 0 ){
                 num &= num  - 1;
                 count++;
            }
            return count;
        }
    View Code

  • 相关阅读:
    [LA] 3027
    [POJ] 3264 Balanced Lineup [ST算法]
    [LA] 3644
    [Codeforces Round #248 (Div. 2)] B. Kuriyama Mirai's Stones
    [Codeforces Round #248 (Div. 2)] A. Kitahara Haruki's Gift
    [Codeforces Round #247 (Div. 2)] B. Shower Line
    [Codeforces Round #247 (Div. 2)] A. Black Square
    [UVA] 784
    [OpenJudge] 百练2754 八皇后
    449 Set、Map数据结构
  • 原文地址:https://www.cnblogs.com/huozhonghun/p/14951883.html
Copyright © 2011-2022 走看看