剑指Offer(二)

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

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。

给定 target = 20,返回 false。

思路(参考题解)

从左下角开始遍历,i表示行,j表示列。i从最大行开始遍历(matrix.length - 1),如果目标值<当前值,说明该行大于目标值,因为是行递增的;j从第0列开始遍历,如果目标值>当前值,说明该行后面可能有满足条件的值,列方向往后移。找到满足条件的值返回true

public class findNumberIn2DArray {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        //(从左下角开始)i:行 j:列
        int i = matrix.length - 1, j = 0;
        while (i >= 0 && j < matrix[0].length) {
            //如果目标值<当前值,说明该行大于目标值,因为是行递增的
            if (target < matrix[i][j]) {
                i --;
                //如果目标值>当前值,说明该行后面可能有满足条件的值,列方向往后移
            } else if (target > matrix[i][j]) {
                j ++;
            } else {
                //找到目标值,返回true
                return true;
            }
        }
        return false;
    }
}
2、剑指 Offer 11. 旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为1。

示例 1:

输入:[3,4,5,1,2]
输出:1

思路:

暴力解法:遍历查找最小值

public int minArray(int[] numbers) {
        //暴力解法
        int res = numbers[0];
        for (int i = 1; i < numbers.length; i ++) {
            if (numbers[i] < res) {
                res = numbers[i];
            }
        }
        return res;
    }

二分法

最小值元素一定在右排序数组中,因此通过二分法找到右排序数组,其中首位就是最小值。本题使用j与mid的值进行比较,从而缩小区间,不能用i,因为当mid>i时,无法判断mid在哪个排序数组中 ,如果与j比较,j肯定在右排序数组中。

    public int minArray2(int[] numbers) {
        //二分法
        //旋转数组 最小值肯定在右排序数组
        int i = 0, j = numbers.length - 1;
        while (i < j) {
            int mid = (i + j) / 2;
            //mid在左排序数组中
            if (numbers[mid] > numbers[j]) {
                i = mid + 1;
                //mid在右排序数组中
            } else if(numbers[mid] < numbers[j]) {
                j = mid;
            } else {
                j --;
            }
        }
        return numbers[i];
    }
}
3、剑指 Offer 50. 第一个只出现一次的字符

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

示例 1:

输入:s = “abaccdeff”
输出:‘b’

思路:哈希表

先将字符串转为字符数组,第一次遍历,如果该字符是第一次出现,添加键值对dic(c,true),如果不是第一次出现,则添加键值对dic(c,false);第二次遍历,查找第一个值为true的字符,找到返回字符。如果没有,返回空格。

public class firstUniqChar {
    public char firstUniqChar2(String s) {
        //参考题解 哈希表
        //dic(c,true)
        HashMap<Character, Boolean> dic = new HashMap<Character, Boolean>();
        char[] sc = s.toCharArray();//字符串转为字符数组
        //第一次遍历,将所有字符添加到map
        for (char c : sc) {
            //如果map中不包含字符c,第一次出现,添加键值对dic(c,true)
            if (! dic.containsKey(c)) {
                dic.put(c, true);
            } else {
                //如果包含了字符c,说明重复出现,添加键值对dic(c,false)
                dic.put(c, false);
            }
        }
        //第二次遍历,返回map中的第一个值
        for (char c : sc) {
            //dic.get(c)为true,说明只出现了1次,返回
            if (dic.get(c)) {
                return c;
            }
        }
        return ' ';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值