程序员面试金典8.*

news2024/9/22 13:42:32

文章目录

  • 8.1三步问题
  • 8.2迷路的机器人
  • 8.3魔术索引
  • 8.4求幂集
  • 8.5递归乘法
  • 8.6 汉诺塔
  • 8.7无重复字符串的排列组合(☆)
  • 8.8有重复字符的排列组合
  • 8.9括号
  • 8.10颜色填充
  • 8.11硬币
  • 8.12八皇后

8.1三步问题

在这里插入图片描述
一个基础的动态规划问题,pass
dp[i]=dp[i-1] + dp[i-2] +dp[i-3]
dp[1]=1, dp[2]=2, dp[3]=4

class Solution {
    public int waysToStep(int n) {
        if(n==1) return 1;
        if(n==2) return 2;
        if(n==3) return 4;
        int a=1,b=2,c=4;
        int ans=0;
        for(int i=4;i<=n;i++){
            ans=((a+b)%1000000007+c)%1000000007;
            a=b;
            b=c;
            c=ans;
        }
        return ans%1000000007;
    }
}

8.2迷路的机器人

在这里插入图片描述

class Solution {
    public List<List<Integer>> pathWithObstacles(int[][] obstacleGrid) {
        int row = obstacleGrid.length;
        int col = obstacleGrid[0].length;
        List<List<Integer>> list = new ArrayList<>();
        boolean[][] dp = new boolean[row][col];
        if(obstacleGrid[0][0] == 1 || obstacleGrid[row - 1][col - 1] == 1) return list;
        dp[0][0] = true;
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                if(obstacleGrid[i][j] == 0){
                    if(i > 0){
                        dp[i][j] |= dp[i - 1][j];
                    }
                    if(j > 0){
                        dp[i][j] |= dp[i][j - 1];
                    }
                }
            }
        }
        if(!dp[row - 1][col - 1]) return list;
        int i = row -1, j = col - 1;
        while(i >= 0 && j >= 0){
            list.add(Arrays.asList(i, j));
            if(i > 0 && dp[i - 1][j]){
                i--;
            } else {
                j--;
            }
        }
        Collections.reverse(list);
        return list;

    }
}

先用动态规划的方法搜寻每个位置能不能到,如果能到最终位置,再反向回到(0,0),反正只要一条路即可
注意两个java操作的小细节:
list.add(Arrays.asList(i, j));
Collections.reverse(list);

8.3魔术索引

在这里插入图片描述

class Solution {
    public int findMagicIndex(int[] nums) {
        for(int i=0;i<nums.length; ){
            if(nums[i]==i)
                return i;
            i=Math.max(nums[i],i+1);
        }
        return -1;
    }
}

间隔跳跃索引,pass

8.4求幂集

可以看我以前写的博客->求幂集的更新贴

8.5递归乘法

在这里插入图片描述

public int multiply(int A, int B) {
    int min = Math.min(A, B);
    int max = Math.max(A, B);
    int ans = 0;

    for (int i = 0; min != 0; i++) {
        if ((min & 1) == 1) {
            ans += max << i;
        }
        min >>= 1;
    }

    return ans;
}

思路
首先,求得A和B的最小值和最大值;
然后,可以对其中的最小值当做乘数(为什么选最小值,因为选最小值当乘数,可以算的少),将其拆分成2的幂的和,即
min = a 0 a_0 a0 2 0 2^0 20+ a 1 a_1 a1 2 1 2^1 21+…+ a i a_i ai* 2 i 2^i 2i+… , 其中 a i a_i ai取0或者1.
其实就是用二进制的视角去看待min,比如12用二进制表示就是1100,即1000+0100。举个例子,13 * 12 = 13 * (8 + 4) = 13 * 8 + 13 * 4 = (13 << 3) + (13 << 2);

8.6 汉诺塔

在这里插入图片描述

class Solution {
    public void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
        moveA2C(A,B,C,A.size());

    }
    public void moveA2C(List<Integer>A,List<Integer>B,List<Integer>C,int n){
        if(n==1){
            C.add(A.remove(A.size()-1));
            return ;
        }
        moveA2C(A, C, B, n - 1);    //A中N-1层移到B
		moveA2C(A, B, C, 1);         //A中最后一层移到C
		moveA2C(B, A, C, n-1);     //B的N-1层移到C
    }
}

主要还是注意终止条件,三个子递归倒是很自然。
remove的必须是A.size()-1, 而不能是0.

8.7无重复字符串的排列组合(☆)

在这里插入图片描述

非递归和递归的写法
以前我是用C++的next_permutation写的

class Solution {
public:
    vector<string> permutation(string S) {
        sort(S.begin(), S.end());
        vector<string> res;
        res.push_back(S);
        while(next_permutation(S.begin(), S.end())) {
            res.push_back(S);
        }

        return res;
    }
};

不过Java里面没有这个函数。(当然也可能有,但我懒的去查了)
但是DFS我又不是太懂这个swap

class Solution {
   List<String> list = new ArrayList<>();

    public String[] permutation(String S) {
        permutate(S.toCharArray(), 0);
        String[] res = new String[list.size()];
        for (int i = 0; i < res.length; i++) {
            res[i] = list.get(i);
        }
        return res;
    }

    public void permutate(char[] arr, int first) {
        if (first == arr.length - 1) {
            list.add(new String(arr));
            return;
        }
        for (int i = first; i < arr.length; i++) {
            swap(arr, first, i);
            permutate(arr, first + 1);
            swap(arr, first, i);
        }
    }

    public void swap(char[] arr, int i, int j) {
        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

}

8.8有重复字符的排列组合

在这里插入图片描述
发现这俩就是代码随想录里的9.12和9.13,排列问题(一)和排列问题(二)

8.9括号

在这里插入图片描述

class Solution {
    List<String> res = new ArrayList<>();
    public List<String> generateParenthesis(int n) {
        dfs(n, n, "");
        return res;
    }

    private void dfs(int left, int right, String curStr) {
        if (left == 0 && right == 0) { // 左右括号都不剩余了,递归终止
            res.add(curStr);
            return;
        }

        if (left > 0) { // 如果左括号还剩余的话,可以拼接左括号
            dfs(left - 1, right, curStr + "(");
        }
        if (right > left) { // 如果右括号剩余多于左括号剩余的话,可以拼接右括号
            dfs(left, right - 1, curStr + ")");
        }
    }

}

8.10颜色填充

在这里插入图片描述

class Solution {
    public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
         helper(image, sr, sc, image[sr][sc], newColor);
        return image;

    }
     private void helper(int[][] image, int i, int j, int oldColor, int newColor){
        if(i < 0 || i >= image.length || j < 0 || j >= image[0].length || image[i][j] != oldColor || image[i][j] == newColor) return;
        image[i][j] = newColor;
        helper(image, i+1, j, oldColor, newColor);
        helper(image, i-1, j, oldColor, newColor);
        helper(image, i, j+1, oldColor, newColor);
        helper(image, i, j-1, oldColor, newColor);
    }
}

对上下左右进行修改。再以此为扩展。
如果不是一个岛屿内的(image[i][j]!=oldColor)或者已经被修改过了(image[i][j]==newColor),就不用再改了,直接return;

8.11硬币

完全背包问题
在这里插入图片描述

class Solution {
    private final int mod = 1000000007;
    private final int[] coins = {25,10,5,1};
    public int waysToChange(int n) {
        int[] dp = new int[n + 1];
        dp[0] = 1;
         for(int coin : coins){
            for(int i = coin;i <= n;i++){
                dp[i] = (dp[i] + dp[i - coin]) % mod;
            }
        }
        return dp[n];
    }
}

8.12八皇后

在这里插入图片描述

class Solution {
    private List<List<String>> res = new ArrayList<>(); // 最终答案

    public List<List<String>> solveNQueens(int n) {
        char[][] grid = new char[n][n]; // 定义棋盘
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                grid[i][j] = '.'; // 棋盘初始化默认都是空
            }
        }
        // 占用为true,未占用false
        // 记录第k列有没有被占用
        boolean[] col = new boolean[n];
        // 记录主对角线方向有没有被占用(左上到右下)
        // 该方向的x=row-col是固定的,范围为-n+1~n-1共2n-1个数,n-x之后范围是1~2n-1,用2n的数组就可以容纳
        boolean[] mainDiag = new boolean[2*n];
        // 记录副对角线方向有没有被占用(右上到左下)
        // 该方向的x=row+col是固定的,范围为0~2n-2共2n-1个数,用2n的数组也可以表示2n-1条对角方向
        boolean[] subDiag = new boolean[2*n];
        dfs(0, n, grid, col, mainDiag, subDiag); // 利用dfs为每一个皇后搜索摆放位置
        return res;
    }

    // 策略为每个皇后摆放一行,r代表当前摆放到行index, n为皇后个数,grid棋盘,后面3个冲突检查数组
    public void dfs(int r, int n, char[][] grid, boolean[] col, boolean[] mainDiag, boolean[] subDiag){
        if(r == n){ // 当最后一个皇后摆放完毕(任务成昆!)
            List<String> list = new ArrayList<>(); // 新list记录当前此种摆放结果
            for(int i=0;i<n;i++){ // 每一行
                list.add(new String(grid[i])); // 将char[]转成String添加进去
            }
            res.add(list); // 此种摆放结果添加到结果集
            return; 
        }
        for(int c=0;c<n;c++){ // 对每一列遍历(摆放女王,列也不能重复)
            // 该列空,该位置主对角线方向空,该位置副对角线方向空
            if(!col[c] && !mainDiag[n-r+c] && !subDiag[r+c]){
                // 可以摆放,棋盘记录
                grid[r][c] = 'Q';
                // 更新冲突数组
                col[c] = mainDiag[n-r+c] = subDiag[r+c] = true;
                // 摆放下一个皇后
                dfs(r+1, n, grid, col, mainDiag, subDiag);
                // 撤销操作,不影响下一次摆放
                col[c] = mainDiag[n-r+c] = subDiag[r+c] = false;
                grid[r][c] = '.';
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/133737.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux系统中串口驱动的基本实现原理

大家好&#xff0c;今天主要和大家聊一聊&#xff0c;如何利用linux系统中的串口驱动。 目录 第一&#xff1a;linux系统中UART驱动框架 第二&#xff1a;uart_ops的具体实现 第三&#xff1a;串口驱动设备树的添加 第一&#xff1a;linux系统中UART驱动框架 向SPI一样&am…

ansible第二天作业

## 安装并且配置ansible 1)安装和配置ansible以及ansible控制节点server.example.com如下&#xff1a; 2)创建一个名为/home/student/ansible/inventory的静态库存文件如下所示&#xff1a; 2.1)node1 是dev主机组的成员 2.2)node2是test主机组的成员 2.3)node1和node2是prod主…

【JAVA】生产消费者问题

生产者/消费者问题是一个共享资源的问题&#xff0c;即生产者生产的产品不能超过最大存储量&#xff0c;而消费者消费的产品不能多于剩下的产品数量。 解决方法有很多种&#xff0c;这里通过同步线程锁&#xff1a; synchronized 但是仅仅使用线程锁是不足的&#xff0c;因为…

ElasticsSearch7.6.1学习笔记【狂神说Java】

文章目录一、ElasticSearch概述二、安装elasticsearch-7.6.1&#xff0c;基于windows 101、解压安装包以及目录结构介绍2、安装可视化插件elasticsearch-head3、解决跨域问题三、安装Kibana四、核心概念五、IK分词器插件1、什么是ik分词器2、解压3、进入kibana测试4、自定义扩展…

状态压缩DP——蒙德里安的梦想

状态压缩DP——蒙德里安的梦想一、题目描述二、思路分析1、状态表示——状态压缩2、状态转移3、循环4、初始化三、代码一、题目描述 二、思路分析 这道题中&#xff0c;其实刚一看是非常的抽象的&#xff0c;也是非常麻烦的。麻烦的点在于我们既需要考虑横着放的方块&#xff…

【Linux】shell命令以及运行原理和Linux权限的理解

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f40c; 个人主页&#xff1a;蜗牛牛啊 &#x1f525; 系列专栏&#xff1a;&#x1f6b2;Linux &#x1f4d5; 学习格言&#xff1a;博观而约取&#xff0c;厚积而薄发 …

VBA之正则表达式(39)-- 提取规格数据(2/2)

实例需求&#xff1a;A列为某产品名称&#xff0c;现需要提取其中的规格数据&#xff0c;具体规则如下&#xff1a; 规格数据以如下关键字开头&#xff1a;RO、RE、SQ、SD、QD、OB、HX、ET、QR、D2规则数据可能有多段&#xff08;截图中红色部分&#xff09;提取规格数据之后&…

SpringBoot简单功能分析,静态资源访问和静态资源配置原理解析

目录 1、SpringMVC自动配置概览 2、简单功能分析 2.1、静态资源访问 1、静态资源目录 2、静态资源访问前缀 3、webjar 2.2、欢迎页支持 2.3、自定义 Favicon 2.4、静态资源配置原理 1、SpringMVC自动配置概览 官网Web (spring.io) Spring Boot provides auto-configur…

论文综述——UNIRE: A Unified Label Space for Entity Relation Extraction

UNIRE: A Unified Label Space for Entity Relation Extraction1 任务介绍2 UniRE模型3 实验4 总结1 任务介绍 过构建标签空间来对实体和关系进行联合抽取的方法。 实体关系抽取旨在提取文本中的实体并检测它们的实体类型&#xff0c;以及对每个实体对检测它们的关系。作者提…

MAX78000FTHR简单介绍与初次上手

特点 MAX78000FTHR是基于MAX78000的小型板微控制器单元&#xff08;MCU&#xff09;。 该 MCU 面向在边缘运行的人工智能 (AI) 应用程序。在这种情况下&#xff0c;“边缘”并不意味着技术的前沿&#xff08;尽管这就是芯片&#xff09;&#xff1b;这意味着靠近需要它的地方…

vector对于自定义类型的操作(memcpy浅拷贝问题)

目录 如果对于不涉及资源管理的自定义类型的操作&#xff08;Date&#xff09;&#xff1a; 对涉及资源管理类操作&#xff08;String&#xff09;&#xff1a; 一、插入四个元素&#xff08;代码正常编译没有任何资源泄露问题&#xff09; 二、当插入第五个元素时&#xf…

【C++进阶】Map 和 Set(详解)

&#x1f308;欢迎来到C专栏~~Map 和Set (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort目前状态&#xff1a;大三非科班啃C中&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一句鸡汤&am…

【JavaScript】DOM 的概念、获取DOM元素和操作元素属性

文章目录【JavaScript】DOM 的概念、获取DOM元素和操作元素属性一. 概念二. DOM 操作(1) 获取DOM元素的方式1. document 获取元素方法2. 通过 HTML5 新增的方法获取案例&#xff1a;登录界面密码显示与隐藏(2) 读写元素内部的结构内容1. 改变元素节点里的内容2. 改变元素节点的…

操作系统的基本概念、功能、目标

文章目录&#x1f380;前言&#xff1a;本篇博客知识总览&#x1fa82;操作系统所处位置&#x1f4d6;操作系统的概念&#x1f3af;操作系统的功能和目标&#x1fa85;1.操作系统作为系统资源的管理者&#x1fa85;2.操作系统作为用户与计算机硬件之间的接口&#x1fa85;3.操作…

连接数据库和简单操作数据库

连接数据库和简单操作数据库JDBC程序编写步骤创建一个演员表数据库表的连接前置工作五种连接方式方式五的配置文件配置文件里面的内容通过JDBC进行对actor表操作。ideal执行后的结果数据库actor表结果JDBC程序编写步骤 1.注册驱动-加载Driver类 2.获取连接-得到Connection 3.执…

【阶段一】Python快速入门04篇:运算符、循环语句、条件语句与函数

本篇的思维导图: 运算符 算术运算符 算术运算就是常规的加、减、乘、除类运算。下表为基本的算术运算符及其示例。 描述 代码

【C++常用容器】STL基础语法学习map容器

目录 ●map基本概念 ●map构造和赋值 ●map大小和交换 ●map插入和删除 ●map查找和统计 ●map排序&#xff08;map初始排序顺序为从小到大&#xff0c;用仿函数将其改为从大到小&#xff09; ●map基本概念 map中的所有元素都是pair&#xff0c;pair中第一个元素为key&a…

【WeThinkIn出品】2022年度总结

Rocky Ding公众号&#xff1a;WeThinkIn写在前面 【WeThinkIn出品】栏目专注于分享Rocky的最新思考与经验总结&#xff0c;包含但不限于技术领域。欢迎大家一起交流学习&#x1f4aa; 这篇文章发布的时候&#xff0c;应该已经是2023年了。在这里Rocky祝大家元旦快乐&#xff01…

前端最常用的几个线上设计网站

文章目录前言CoDesign 腾讯自研设计平台【墙裂推荐】蓝湖- 高效的产品设计协作平台【墙裂推荐】zeplin Deliver on the promise of design 【国外&#xff0c;不推荐】总结前言 随着IT技术的不断进步&#xff0c;很多团队都将很对线下工作转移到了线上&#xff0c;不仅便捷&a…

Ae 效果详解:毛边

Ae菜单&#xff1a;效果/风格化/毛边Effects/Stylize/Roughen Edges毛边 Roughen Edges效果可使得 Alpha 通道的边缘变粗糙&#xff0c;可以为图像添加各种边缘效果。通过分形影响改变边缘样式&#xff0c;并可增加颜色以模拟铁锈和其他类型的腐蚀。此效果可为文本或图形提供自…