二分查找/排序

二分查找/排序

BM17 二分查找-I

public class Solution {
    public int search (int[] nums, int target) {
        if(nums.length == 0) return -1;
        int left = 0, right = nums.length - 1;
        while(left <= right){
            int mid = left + (right - left) / 2;
            if(nums[mid] == target) return mid;
            else if(nums[mid] < target) left = mid + 1;
            else right = mid - 1;
        }
        // 没找到,返回-1
        return -1;
    }
}

BM18 二维数组中的查找

public class Solution {
    public boolean Find(int target, int [][] array) {
        int m = array.length, n = array[0].length;
        // 从左上角开始查找
        int row = 0, col = n - 1;
        while(row < m && col >= 0){
            // 找到,返回true
            if(array[row][col] == target) return true;
            else if(array[row][col] > target){
                col--;
            }else{
                row++;
            }
        }
        // 未找到,返回false
        return false;
    }
}

BM19 寻找峰值(注意)

public class Solution {
    public int findPeakElement (int[] nums) {
        /**
        峰值的特点:
        1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于
        2.假设 nums[-1] = −∞, nums[n] = −∞
        3.对于所有有效的 i 都有 nums[i] != nums[i + 1]
        要求时间复杂度为O(logN)
        */
        int left = 0, right = nums.length - 1;
        while(left < right){
            int mid = left + ((right - left) >> 1);
            // left和right均向山峰靠近
            if(nums[mid] > nums[mid + 1]) right = mid;
            else left = mid + 1;
        }
        return left;
    }
}

BM20 数组中的逆序对(归并排序)

public class Solution {
    // 逆序对即为数组排序过程中元素交换的次数
    // 暴力解法可采用冒泡排序算法
    // 这里采用归并排序算法
    
    int count = 0;// 统计交换次数
    public int InversePairs(int [] array) {
        // 归并排序
        sort(array, 0, array.length - 1);
        return count;
    }
    
    /************************归并排序算法*********************************/
    void sort(int[] nums, int left, int right) {
        if (left == right) {// 单一元素,有序,直接返回
            return;
        }
        int mid = left + (right - left) /2;// 取中点划分
        sort(nums, left, mid);// 左边数组排序
        sort(nums, mid + 1, right);// 右边数组排序

        /****** 后序位置 ******/
        // 合并两个排好序的数组
        merge(nums, left, mid, right);
    }

    // 合并两个排好序的子数组
    public void merge(int[] nums, int left, int mid, int right) {
        // 创建一个空辅助数组
        int[] temp = new int[nums.length];
        // 将nums中的数据移到temp中,nums用于存放排序结果
        for (int i = left; i <= right; i++) {
            temp[i] = nums[i];
        }
        // 数组双指针技巧,合并两个有序数组
        int i = left, j = mid + 1;
        for (int p = left; p <= right; p++) {// 通过遍历,将结果存储至nums
            if (i == mid + 1) {// 左半边数组已全部被合并
                nums[p] = temp[j++];// 将右半边剩余内容复制到nums中
            } else if (j == right + 1) {// 右半边数组已全部被合并
                nums[p] = temp[i++];// 将左半边内容复制到nums中
            } else if (temp[i] > temp[j]) {// 左边元素大于右边元素
                
                /***************此时存在逆序对,需进行操作**************************/
                count += (mid + 1 - i);
                count %= 1000000007;
                /***************************************************************/
                nums[p] = temp[j++];
            } else {// 右边元素大于等于左边元素
                nums[p] = temp[i++];
            }
        }
    }
}

BM21 寻找数组中的最小数字(注意)

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
        if(array.length == 0) return -1;
        int left = 0, right = array.length - 1;
        while(left < right){
            // 有序,则left处的元素最小
            if(array[left] < array[right]) return array[left];
            // 无序,二分查找
            int mid = left + (right - left) / 2;
            if(array[mid] > array[right]) left = mid + 1;
            else if(array[mid] < array[right]) right = mid;
            else right--;
        }
        return array[left];
    }
}

BM22 比较版本号

import java.util.*;
public class Solution {
    public int compare (String version1, String version2) {
        // 将版本号划分为修订号字符串
        String[] ver1 = version1.split("\\.");
        String[] ver2 = version2.split("\\.");
        // 获取转换成数字数字的长度
        int len = Math.max(ver1.length, ver2.length);
        int[] verNum1 = new int[len];
        int[] verNum2 = new int[len];
        // 将修订号转换成数字,并存储在数组中
        for(int i = 0; i < len; i++){
            // 转换成数字,自动忽略前导0
            verNum1[i] = i < ver1.length ? stringToNumber(ver1[i]) : 0;
            verNum2[i] = i < ver2.length ? stringToNumber(ver2[i]) : 0;
            // 比较两个修订号
            if(verNum1[i] > verNum2[i]) return 1;
            if(verNum1[i] < verNum2[i]) return -1;
        }
        return 0;
    }
    
    // 将字符串转化为数字
    public int stringToNumber(String str){
        char[] chars = str.toCharArray();
        int number = 0;
        for(int i = 0; i < chars.length; i++){
            number = number * 10 + (chars[i] - '0');
        }
        return number;
    }
}
全部评论

相关推荐

Noel_:中石油是这样的 哥们侥幸混进免笔试名单 一看给我吓尿了
点赞 评论 收藏
分享
一名愚蠢的人类:多少games小鬼留下了羡慕的泪水
投递荣耀等公司10个岗位
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务