(剑指Offer)面试题11. 旋转数组的最小数字 & 面试题12. 矩阵中的路径

面试题11. 旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

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

输入:[2,2,2,0,1]
输出:0

思路
这个问题用暴力算法的话,简单来说是寻找数组最小值问题,(题目给定输入是递增排序的数组的一个旋转,也就是说,一般情况下第一个元素(最小的元素)旋转到了数组后面的某个位置)有很多种方法可以用,笔者在这里用了相邻元素的比较。

class Solution {
    public int minArray(int[] numbers) {
        if(numbers.length == 0) return 0;
        if(numbers.length == 1) return numbers[0];
        int i = 0;
        for(; i < numbers.length - 1; i++){
            //每个元素都与前一个元素比较,若比前面元素小,则跳出循环返回
            if(numbers[i + 1] < numbers[i]){
                break;
            }
            //说明是递增序列,返回numbers[0]
            if(i == numbers.length - 2 && numbers[i + 1] >= numbers[i])return numbers[0];
        }             
        return numbers[i + 1];
    }
}

还可以使用二分法:排序数组的查找问题可以首先考虑使用二分法解决,通常可以将需要遍历的算法时间复杂度由O( N )降为O(log N),有时候会有更优解出现

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];
    }
}

面试题12. 矩阵中的路径

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。
例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。

[[“a”,“b”,“c”,“e”],

[“s”,“f”,“c”,“s”],

[“a”,“d”,“e”,“e”]]

但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false

限制:
1 <= board.length <= 200
1 <= board[i].length <= 200

思路:深度优先搜索(DFS)

class Solution {
    public boolean exist(char[][] board, String word) {
        char[] words = word.toCharArray();
        for(int i = 0; i < board.length; i++) {
            for(int j = 0; j < board[0].length; j++) {
                if(dfs(board, words, i, j, 0)) return true;
            }
        }
        return false;
    }
    boolean dfs(char[][] board, char[] words, int i, int j, int k) {
        //越界或者不匹配,返回false
        if(i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != words[k]) return false;
        if(k == words.length - 1) return true;
        char tmp = board[i][j];
        //访问过的做标记
        board[i][j] = '/';
        boolean res = dfs(board, words, i + 1, j, k + 1) || dfs(board, words, i - 1, j, k + 1) || 
                      dfs(board, words, i, j + 1, k + 1) || dfs(board, words, i , j - 1, k + 1);
        //标记还原
        board[i][j] = tmp;
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值