前言
- 以下提到的一些练习题均为掘金青训营官方账号发布的练习题。详细内容可以在官方号上查看。
- 以下提到的代码片段我也发布在了码上掘金。
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