剑指offer12-16

11 篇文章 0 订阅
7 篇文章 0 订阅
本文介绍了LeetCode中的四道算法题目,包括矩阵中查找特定单词的路径、机器人在方格中的运动范围、剪绳子以获得最大乘积和计算二进制中1的个数。每道题目都提供了详细的解题思路和代码实现,旨在帮助读者理解和解决这类算法问题。
摘要由CSDN通过智能技术生成

你未必出类拔萃,但一定与众不同

剑指offer 12-16

题12 矩阵中的路径

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof

public boolean exist(char[][] board, String word) {
        if (board == null || board.length == 0 || board[0].length == 0) {
            return false;
        }
		//拆分字符串为一个一个字符
        char[] chars = word.toCharArray();
    	//定义一个boolean数组 判断当前的节点是否走过
        boolean[][] visited = new boolean[board.length][board[0].length];
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                //从左边第一个点挨个去找路径
                if (dfs(board, chars, visited, i, j, 0)) {
                    return true;
                }
            }
        }
        return false;
    }

	//开始进行dfs深搜
    private boolean dfs(char[][] board, char[] chars, boolean[][] visited, int i, int j, int start) {
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length
                || chars[start] != board[i][j] || visited[i][j]) {
            return false;
        }
        if (start == chars.length - 1) {
            return true;
        }
        visited[i][j] = true;
        boolean ans = false;
        ans = dfs(board, chars, visited, i + 1, j, start + 1)
                || dfs(board, chars, visited, i - 1, j, start + 1)
                || dfs(board, chars, visited, i, j + 1, start + 1)
                || dfs(board, chars, visited, i, j - 1, start + 1);
        //这里需要复位是因为 如果这条路线走不通 那么需要把走过的位置都复位,方便下一次重新开始
        //如果直接找到了路径 就会直接返回true
        visited[i][j] = false;
        return ans;
    }

在这里插入图片描述

题13 机器人的运动范围

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof

思路:

  • 可以将这个方格也看做一个矩阵
  • 机器人能够正式进入格子 需要进行判断 也就是 i j 的数位相加必须小于等于 k的值
  • 机器人进入格子开始移动的时候,从坐标[0,0] 开始移动 此时他可以选择 向右或者 向下移动 事实上此时边界就出来了 因为 机器人如果在中间位置 可以 左右上下移动
  • 设置一个boolean类型的二维数组来进行判断 是否都经过了这个坐标的位置 防止重复移动。
  • 然后通过将经过的路径相加 就可得到
class Solution {
    public static int movingCount(int m, int n, int k) {
        int[][] number = new int[m][n];
        boolean[][] visited = new boolean[number.length][number[0].length];
        int result = dfs(number,k,visited,0,0);
        return result;
    }
    public static int dfs(int[][] number,int k,boolean[][] visited,int i,int j){
        if(i < 0 || j < 0 || i >= number.length || j >= number[0].length || visited[i][j]){
            return 0;
        }
        int count = 0;
        if(sum(i,j) <= k){
            visited[i][j] = true;
            count = 1 + dfs(number,k,visited,i+1,j)
                    +dfs(number,k,visited,i,j+1)
                    +dfs(number,k,visited,i-1,j)
                    +dfs(number,k,visited,i,j -1);
        }
        return count;
    }


    public static int sum(int a,int b){
        int sum1 = 0;
        int sum2 = 0;
        while(a > 0){
            sum1 += a % 10;
            a = a/10;
        }
        while(b > 0){
            sum2 += b % 10;
            b = b/10;
        }
        return sum1 + sum2;
    }
}

在这里插入图片描述

题14 剪绳子

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof

思路:

  • 这道题有点难,当时没有头绪,然后就自己把 绳子长写出来

    4 : 2 * 2 = 1 * 3

    5 :2 * 3

    6 :3* 3

    7:3*4

    8:3* 3*2

    9:3 * 3 * 3

    慢慢推导 发现拆分成3 值是最大的 4 那个就是 2 2 大于3 其他7的话就是 3 * 4 8= 3 3 *2 当时没想到为啥 后面看了解法才发现里面还有求极值

  • 然后就是求当前绳长的两个因素 一个是除出来的商 一个就是余数

  • 余数为0 的时候 就是刚好是 3 * 3连续乘法

  • 余数为1 的时候 就是余数为4 也就是拆分前面的那个 4 : 2 *2 > 1 *3

  • 余数为2 的时候 就是3 * 3 连乘 乘以余数2

class Solution {
    public int cuttingRope(int n) {
        if(n <= 3){
            return n - 1;
        }
        int a = n / 3;
        int b = n % 3;
        if(b == 0){
            return (int) Math.pow(3 , a);
        }
        if(b == 1){
            return (int) Math.pow(3 , a - 1) * 4;
        }
        return (int)Math.pow(3 , a) * 2;
    }
}

在这里插入图片描述

题15 二进制中1的个数

编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为 汉明重量).)。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof

思路:

采用&运算

0 & 0 = 0;

0 & 1 = 0;

1 & 1 = 1;

使用与运算 让n的最低位每次都与1做与运算 低位若为1则结果1 不为1 则结果为0

>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。

然后再使 n 右移一位即可 使用>>> 再进行比较

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int number = 0;
        while(n != 0){
            if((n & 1) == 1){
                number ++;
            }
           n =  n >>>1;
        }
        return number;
    }
}

在这里插入图片描述

题16 数值的整数次方

实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。不得使用库函数,同时不需要考虑大数问题。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof

思路:

当指数为负数时, 先对指数求绝对值,然后再取当前需要求的数的倒数

通过循环 result负责确定最终结果的正负。

class Solution {
    public double myPow(double x, int n) {
        long flag = n;
        double result = 1.0;
        if(n == 0){
            return 1;
        }
        if(x == 1){
            return x;
        }
        if(flag < 0){
            flag = -flag;
            x = 1/x;
        }
        while(flag > 0) {
            //判断当前的数是否是奇数
            if((flag & 1) == 1){
                result = result * x;
            }
            x = x * x;
            //右移运算符代替2
            flag = flag >> 1;
        }
        return result;
    }
}

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼爱吃柚子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值