查找算法(Java)

1. 剑指 Offer 03. 数组中重复的数字

原题链接
在这里插入图片描述
HashSet

/*
	1. 新建 HashSet dic。
	2. 遍历 nums。
	   1) num在dic中,说明重复则返回num。
	   2)不在dic中,将num添加到dic中。
*/
class Solution {
    public int findRepeatNumber(int[] nums) {
        Set<Integer> dic = new HashSet<>();
        for(int num:nums){
            if(dic.contains(num)) return num;
            else dic.add(num);
        }
        return -1;
    }
}


2. 剑指 Offer 04. 二维数组中的查找

原题链接
在这里插入图片描述
二分查找

/*
	1. 一个这样的二维数组,看右上角的元素,它右下的数字比它小,左上的数字比它大。
	   【或左下角的元素,左上的数字比它小,右下的数字比它大】
	2. 基于此,可以进行二分查找。
	3. 从左下角元素开始遍历,即matrix[matrix.length-1][0]
	   【用右上角元素遍历的话,求matrix[0][matrix[0].length-1]可能会报错】
	4. target目标值大于此元素 j++,小于此元素 i--。
*/
class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        int i = matrix.length-1,j = 0;
        while(i >=0 && j < matrix[0].length){
            int flag = matrix[i][j];
            if(target < flag) i--;
            if(target > flag) j++;
            if(target == flag) return true;
        }
        return false;
    }
}


3. 剑指 Offer 11. 旋转数组的最小数字

原题链接
在这里插入图片描述
二分查找

/*
	1. 旋转排序数组是局部有序的,从旋转点分开可分成左排序数组和右排序数组。
	2. 用二分法寻找旋转点。
	3. i,j 指向数组的两端,m = (i+j)/2
	4. if(nums[m] > nums[j]) 旋转点在[m+1, j]闭区间中
	   if(nums[m] < nums[j]) 旋转点在[i, m]闭区间中
	   if(nums[m] == nums[j]) 无法判断在哪个区间中,缩小j值,继续循环
*/
class Solution {
    public int minArray(int[] numbers) {
        // 初始化
        int i=0, j=numbers.length-1;
        while(i < j){
            int m = (i+j)/2;
            if(numbers[m] > numbers[j]) i = m+1;
            else if(numbers[m] < numbers[j]) j = m;
            else j--;
        }
        return numbers[i];
    }
}


4. 剑指 Offer 50. 第一个只出现一次的字符

原题链接
在这里插入图片描述
HashMap

/*
	1. 新建 HashMap dic。
	2. 将字符串s转为字符数组。
	3. 遍历字符数组,判断dic中是否存在 c。
	   1)存在添加键值对(c, false)
	   2)不存在添加键值对(c, true)
	4. 找到第一个为true的字符。
*/
class Solution {
    public char firstUniqChar(String s) {
        HashMap<Character, Boolean> dic = new HashMap<>();
        char[] sc = s.toCharArray();
        for(char c : sc){
            dic.put(c, !dic.containsKey(c));
        }
        for(char c : sc){
            if(dic.get(c)) return c;
        }
        return ' ';
    }
}


5. 剑指 Offer 53 - I. 在排序数组中查找数字 I

原题链接
在这里插入图片描述
二分查找

/*
	1. 两次二分,找到所找值的左边界和右边界
	2. 与一般二分法不同的是 if(nums[m] == target)
	   找左边界  right = m-1
	   找右边界  left = m+1
	3. 出现次数 = right-left-1
*/
class Solution {
    public int search(int[] nums, int target) {
        int i=0, j=nums.length-1;
        int m,left,right;
        // 找左边界
        while(i <= j){
            m = (i+j)/2;
            if(nums[m] > target) j = m-1;
            else if(nums[m] < target) i = m+1;
            else j = m-1;
        }
        left = j;
        // 找右边界
        i=0;j=nums.length-1;
        while(i <= j){
            m = (i+j)/2;
            if(nums[m] > target) j = m-1;
            else if(nums[m] < target) i = m+1;
            else i = m+1;
        }
        right = i;
        // 是否存在target值
        if(j >= 0 && nums[j] != target) return 0;
        return right-left-1;
    }
}


6. 剑指 Offer 53 - II. 0~n-1 中缺失的数字

原题链接
在这里插入图片描述
二分查找

/*
	1. 比较索引与索引对应值的关系进行二分
	2. if(m == nums[m]) i = m+1
	   else j = m-1;
*/
class Solution {
    public int missingNumber(int[] nums) {
        int i=0, j=nums.length-1;
        while(i<=j){
            int m = (i+j)/2;
            if( m == nums[m]) i = m+1;
            else j = m-1;
        }
        return i;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值