【青训营】编程题分析

1,041 阅读3分钟

前言

  • 以下提到的一些练习题均为掘金青训营官方账号发布的练习题。详细内容可以在官方号上查看。
  • 以下提到的代码片段我也发布在了码上掘金。

36进制加法

题目

实现36进制加法(0-9 a-z)

思路

进制问题要处理好两个内容:

  • 本位
  • 进位

代码

import java.util.*;
/*实现36进制的加法
思路:记录当前位和进位
*/


public class Main {
   static  String dir="0123456789abcdefghijklmnopqrstuvwxyz";
   public static void main(String []args) {
    System.out.println(add("abbbb","1"));
   }

   public static String add(String num1,String num2){
       StringBuilder sb=new StringBuilder();
       int carry=0;
       int m=num1.length(),n=num2.length();
       for(int i=m-1,j=n-1;i>=0||j>=0||carry!=0;){
            if(i>=0){
               carry+=dir.indexOf(num1.charAt(i));
               i--;
            }
            if(j>=0){
               carry+=dir.indexOf(num2.charAt(j));
               j--;
            }
            sb.append(dir.charAt(carry%36));
            carry/=36;
       }
       return sb.reverse().toString();
   }
}

代码链接:青训营-36进制

最大可推荐相邻座位数

题目

抖音电影票业务支持电影院选座,需要在用户买票时自动推荐座位,如果一个用户买了多张票,则需要推荐相邻(上下相邻、左右相邻都可)的座位。现在使用一个二维数组来表示电影院的座位,数组中 0 表示未被选座,1 表示已被选座或者为障碍物,请实现一个方法求出给定影院中 最大 可推荐的相邻座位个数。 测试用例: [1,0,0,1,0,0,0]

[1,0,0,0,0,1,1]

[0,0,0,1,0,0,0]

[1,1,0,1,1,0,0]

输出:18

思路

这题和力扣上的岛屿数量很相似。

但也有不同,这里是用dfs统计符合相邻条件的 最大 0 的数量

代码

public class Main {
   public static void main(String []args) {
      int [][] grid={{1,0,0,1,0,0,0},{1,0,0,0,0,1,1},{0,0,0,1,0,0,0},{1,1,0,1,1,0,0}};
      int n=grid.length;//4
      int m=grid[0].length;//7
      int res=0;
      for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
          if(grid[i][j]==0){
            res=Math.max(res,dfs(grid,i,j));
          }
        }
      }
      System.out.println(res);
   }

   public static int dfs(int [][] grid,int i,int j){
      int n=grid.length;//4
      int m=grid[0].length;//7

      //边界处理
      if(i<0||i>=n||j<0||j>=m) return 0;
      if(grid[i][j]==1) return 0;

      int cnt=1;
      grid[i][j]=1;
      cnt+=dfs(grid,i+1,j);
      cnt+=dfs(grid,i,j+1);
      cnt+=dfs(grid,i-1,j);
      cnt+=dfs(grid,i,j-1);
      return cnt;
   }
}

代码链接青训营——最大可推荐相邻座位数

复原ip

题目

有效 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

例如:"0.1.2.201" 和 "192.168.1.1" 是有效 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是无效 IP 地址。

给定一个字符串 s,非数字的字符可替换为任意不包含在本字符串的数字,同样的字符只能替换为同样的数字,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你不能重新排序或删除 s 中的任何数字,你可以按任何顺序返回答案。

输入1: 输入:20212118136

输出:

20.212.118.136

202.12.118.136

202.121.18.136

202.121.181.36

输入2: 输入:11a2b22a037

输出:114.252.240.37

思路

这题应是取自剑指offer原题:复原ip。但两者又有不同之处。比如非数字字符可以替换为不在本字符串中的数字。

我下面的代码仅仅是解决了初始的复原ip问题,还没有解决替换字符串的问题。 (我有个初步的想法,就是用散列的原理,比如默认将a转成0,b转成1,但是如果0已经有了,就后移一位,看看1有没有被占用,依次类推。 如果找到了合适的,就把它存到Map里)

希望看到文章的掘金大佬们不吝赐教,一起补充!非常感谢!

代码

public class Main {
  static int [] ip=new int [4];
  static String s="20212118136";
  static int n=s.length();
  static List<String> res=new ArrayList<>();
   public static void main(String []args) {
      //初筛长度就不符合条件的
      if(n<4||n>12) System.out.println("没有符合条件的结果");
      else{
          dfs(0,0);
          if(res.size()==0) System.out.println("没有符合条件的结果");
          else{
            for(int i=0;i<res.size();i++){
                System.out.println(res.get(i));
                System.out.println();
            }
          }
      }
   }

   public static void dfs(int index,int cnt){
     StringJoiner sj=new StringJoiner(".");
        if(cnt==4){
            if(index==n){
                for(int x:ip){
                    sj.add(x+"");
                }
                res.add(sj.toString());
            }
            return ;
        }

        //剪枝,字符数与点数的相对数量异常
        if(n-index<4-cnt||n-index>(4-cnt)*3) return ;

        int segment=0;
        for(int i=index;i<index+3&&i<n;i++){
            segment=segment*10+(s.charAt(i)-'0');
            //边界合法性检查
            if(segment<0||segment>255) return ;
            ip[cnt]=segment;
            dfs(i+1,cnt+1);
            if(segment==0) return ;
        }
    }
   }

代码链接青训营-复原ip