赞
踩
1、判断输入的密码是否正确,比如要求长度大于8,包含至少一个大写,一个小写,一个特殊字符:
这段代码定义了一个PasswordChecker类,其中包含一个静态方法isPasswordValid,该方法接受一个密码字符串作为参数,并返回一个布尔值,表示密码是否有效。如果密码长度大于8,且包含至少一个大写字母、一个小写字母和一个特殊字符,则返回true,否则返回false。main方法提供了一个简单的示例,用于测试这个方法。
import java.util.regex.Pattern; public class PasswordChecker { private static final Pattern SPECIAL_CHAR_PATTERN = Pattern.compile("[^a-zA-Z0-9]"); public static boolean isPasswordValid(String password) { if (password == null || password.length() < 9) { return false; } boolean hasUpperCase = false; boolean hasLowerCase = false; boolean hasSpecialChar = SPECIAL_CHAR_PATTERN.matcher(password).find(); for (int i = 0; i < password.length(); i++) { char c = password.charAt(i); if (Character.isUpperCase(c)) { hasUpperCase = true; } else if (Character.isLowerCase(c)) { hasLowerCase = true; } if (hasUpperCase && hasLowerCase && hasSpecialChar) { return true; } } return hasUpperCase && hasLowerCase && hasSpecialChar; } public static void main(String[] args) { String password = "Example!12"; boolean valid = isPasswordValid(password); System.out.println("Password is valid: " + valid); } }
2、贪心的猴子,按照一定规则去拿香蕉,拿N次,最多能拿到多少:
首先按照香蕉的价值将它们进行排序,然后贪心地挑选最贵的香蕉。这种策略在所有情况下都能得到最优解,但它有一个假设前提:贪心策略总是能得到全局最优解。
public int maxNutCount(int[] values, int N) {
Arrays.sort(values); // 按价值排序
int sum = 0;
for (int i = 0; i < N; i++) {
sum += values[values.length - 1 - i]; // 挑选最贵的香蕉
}
return sum;
}
3、二维数组轮询跳跃删除问题:
这段代码实现了一个函数jumpDelete,它接受一个整数数组和一个整数k作为参数,并返回一个经过处理的数组。在这个数组中,每隔k-1个元素会跳过一个元素。如果原数组的长度小于k,则直接返回原数组。
public class ArrayJumpDelete { public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5}; int k = 2; int[] result = jumpDelete(array, k); for (int value : result) { System.out.print(value + " "); } } private static int[] jumpDelete(int[] array, int k) { if (array == null || array.length == 0 || k <= 1) { return array; } int length = array.length; int step = 1; int[] newArray = new int[length]; for (int i = 0, j = 0; i < length; i++) { newArray[j++] = array[i]; step++; if (step == k) { i++; // 跳过下一个元素 step = 1; } } // 如果新数组的长度小于原数组,需要重新分配大小 if (newArray.length > j) { int[] trimmedArray = new int[j]; System.arraycopy(newArray, 0, trimmedArray, 0, j); return trimmedArray; } return newArray; } }
4、二维数组中指定元素边界相邻问题:
这段代码定义了一个findBoundaryNeighbors方法,用于查找并返回指定元素在二维数组中的上下边界相邻元素。如果找不到相邻元素,则在返回的数组中对应位置填充-1。在main方法中,我们创建了一个示例矩阵并调用了这个方法,输出了结果。
public class BoundaryNeighbors { // 查找并返回指定元素在二维数组中的边界相邻元素 public static int[] findBoundaryNeighbors(int[][] matrix, int element) { int[] neighbors = new int[2]; // 初始化为-1,表示未找到 Arrays.fill(neighbors, -1); // 遍历二维数组,查找指定元素 for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[i].length; j++) { if (matrix[i][j] == element) { // 检查边界相邻元素 if (i > 0 && matrix[i - 1][j] != element) { neighbors[0] = matrix[i - 1][j]; } if (i < matrix.length - 1 && matrix[i + 1][j] != element) { neighbors[1] = matrix[i + 1][j]; } break; // 找到后退出内层循环 } } } return neighbors; } public static void main(String[] args) { int[][] matrix = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; int element = 5; int[] neighbors = findBoundaryNeighbors(matrix, element); // 输出结果 System.out.println("上边界相邻元素: " + (neighbors[0] == -1 ? "N/A" : neighbors[0])); System.out.println("下边界相邻元素: " + (neighbors[1] == -1 ? "N/A" : neighbors[1])); } }
5、题目描述
【篮球比赛】
10个篮球队员的战斗力(整数,范围[1, 10000]),战斗力之间用空格分隔,如:10987654321
不需要考虑异常输入的场景。
【输出描述】
最小的战斗力差值,如:1
【示例1】
【输入】
10 9 8 7 6 5 4 3 2 1
【输出】
说明: .
1 2 5 9 10分为一队,3 4 6 7 8分为一队,两队战斗之差最小,输出差值1。
备注:球员分队方案不唯一 ,但最小战斗力差值固定是1。
该题类似于将10个数分成两组,使得两组的数和之差最小。最小战斗力从差值0开始,不满足依次增加,差值为0,即将10个战斗力之和平分给两组,若无法平分则不满足,差值增加。若满足则利用回溯算法统计满足选出5个数且之后恰好为平均值的数。
import java.util.Arrays; import java.util.Scanner; /** * @Author * @Date 2023/6/11 15:15 */ public class 篮球比赛 { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { int[] array = Arrays.stream(in.nextLine().split(" ")) .mapToInt(Integer::parseInt).toArray(); int totalSum = 0; for (int arr : array) { totalSum += arr; } // 从0开始找最小差值战斗力 for (int i = 0; i <= totalSum; i++) { int target = (totalSum - i); if (target % 2 == 0) { // 总和减去差值可以被平分为两组 if (dfs(array, 0, target / 2, new boolean[10])) { System.out.println(i); // 能匹配则输出 break; } } } } } // 回溯 遍历搜索分配球员 public static boolean dfs(int[] array, int startIndex, int sum, boolean[] used) { if (startIndex > 5 || sum < 0) { return false; } if (startIndex == 5 && sum == 0) { return true; } for (int i = 0; i < array.length; i++) { if (used[i]) { continue; } used[i] = true; if (dfs(array, startIndex + 1, sum - array[i], used)) { return true; } used[i] = false; // 回溯 不选 } return false; } }
6、一个有N个选手参加比赛,选手编号为1~N(3<=N<=100),有M(3<=M<=10)个评委对选手进行打分。
打分规则为每个评委对选手打分,最高分10分,最低分1分。
请计算得分最多的3位选手的编号。
如果得分相同,则得分高分值最多的选手排名靠前
(10分数量相同,则比较9分的数量,以此类推,用例中不会出现多个选手得分完全相同的情况)。
????
7、该题类似于将10个数分成两组,使得两组的数和之差最小。最小战斗力从差值0开始,不满足依次增加,差值为0,即将10个战斗力之和平分给两组,若无法平分则不满足,差值增加。若满足则利用回溯算法统计满足选出5个数且之后恰好为平均值的数。
这段代码使用了一个位掩码来表示哪些数字被分配到第一组。例如,如果i是二进制的10(即十进制的2),那么第二个和第四个数字会被分配到第一组。然后计算这两个组的和,并更新最小差值。这个过程会重复进行,直到所有可能的分组情况都被尝试过。
public class MinimumGroupsDifference { public static void main(String[] args) { int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int minDifference = Integer.MAX_VALUE; // 尝试所有可能的分组组合 for (int i = 0; i < (1 << numbers.length); i++) { int sumGroup1 = 0; int sumGroup2 = 0; // 计算两个组的和 for (int j = 0; j < numbers.length; j++) { if (isBitSet(i, j)) { sumGroup1 += numbers[j]; } else { sumGroup2 += numbers[j]; } } // 更新最小差值 int difference = Math.abs(sumGroup1 - sumGroup2); minDifference = Math.min(minDifference, difference); } // 输出最小差值 System.out.println("最小的数字和之差为: " + minDifference); } // 检查第i位是否为1 private static boolean isBitSet(int num, int i) { return (num & (1 << i)) != 0; } }
8、小华按照地图去寻宝,地图上被划分成m行和n列的方格,横线坐标范围分别是[0,n-1]和[0,m-1]。在横坐标和纵坐标的数位之和不大于k的方格中存在黄金(每个方格中仅存在一克黄金)。但是横坐标和纵坐标之和大于k的方格存在危险不可进入。小华
从入口(0,0)进入。任何时候只能向左,右,上,下四个方向移动一格。
请问小华最多能获得多少克黄金?
输入描述:坐标取值范围如下:
0<=m<=50
0<=n<=50
k的取值范围如下:
0<=k<=100
输入中包含3个字数,分别是m,n,k
最多能获得多少克黄金?
???
9、在学校中,N个小朋友站成一队,第i个小朋友的身高为height[i],
第i个小朋友可以看到的第—个比自己身高更高的小朋友j,
那么j是i的好朋友(要求j>i)。
请重新生成一个列表,对应位置的输出是每个小朋友的好朋友位置,如果没有看到好朋友,请在该位置用o代替代替。
小朋友人数范围是[0, 40000]
第一行输入N,N表示有N个小朋友
第二行输入N个小朋友的身高height[i],都是整数
输出N个小朋友的好朋友的位置
题意解读:
这个题目意思是,给定一列小朋友站成一队,每个小朋友有一个身高值。我们输入的就是这些小朋友的身高。对于队列中的每一个小朋友,我们要找出站在他后面的、并且比他更高的第一个小朋友的位置。
以 123 124 125 121 119 122 126 123 为例,他表示这八个小朋友的身高。
第 0 个小朋友身高123:我们需要找到他的后面,第一个比他高的小朋友。于是我们找到了身高为 124 的小朋友。而 124 的索引为 2,所以 123 的好朋友是在位置 1。
第 1 个小朋友身高124:向后看,第一个比他高的是125的小朋友,所以125的好朋友是在位置2。
第 2 个小朋友身高125:向后看,直到找到126的小朋友,因为他是唯一一个比125高的,所以125的好朋友是在位置 6。
后面的以此类推,对于每个小朋友,都往后找,找到第一个身高比他高的小朋友的索引,就能得出答案。
所以正确的答案是 [1, 2, 6, 5, 5, 6, 0, 0]。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 小朋友的数量 int n = scanner.nextInt(); int[] heights = new int[n]; // 每个小朋友的身高 for (int i = 0; i < n; i++) { heights[i] = scanner.nextInt(); } //找到下一个更高的小朋友 int[] result = findNextTaller(heights); for (int position : result) { System.out.print(position + " "); } scanner.close(); } public static int[] findNextTaller(int[] heights) { int n = heights.length; int[] result = new int[n]; // 默认初始化为0,表示没有找到好朋友的情况 for (int i = 0; i < n; i++) { result[i] = 0; } // 对每个小朋友,向后查找第一个比他高的小朋友 for (int i = 0; i < n - 1; i++) { // 最后一个小朋友后面没有小朋友了,所以不用检查 for (int j = i + 1; j < n; j++) { if (heights[j] > heights[i]) { result[i] = j; // 记录找到的第一个比当前小朋友高的小朋友的索引 break; // 找到后就不再继续向后查找 } } } return result; } }
10、和小船今天又玩起来了数字游戏,小船给小扇一个正整数n(1<=n<=1e9),
小扇需要找到一个比n大的数字m,使得m和n对应的二进制中1的个数要相同(如4对应二进制100,8对应二进制1000,1的个数都为1),
现在求m的最小值
输入:第一行输入一个整数n(1<=n<=1e9)
输出:一个正整数m
例如输入7,
输出11.用Python ,不要调用函数
python–忽略
11、求指定的像素位置的值
计算机在存储图像时会把图像分成像素矩阵,矩阵的每个格表示灰度值,其中
0 表示纯黑,255 表示纯白,按如下要求输入一个矩阵,输出矩阵指定位置的灰
度值。
10 10 255 34 0 8 ……
3 4
其中第一行输入的是矩阵信息,前两个数分别代表矩阵的行数和列数,接下来
的值成对出现,第一个值表示连续重复多少次,第二个值表示灰度值。比如上
述输入表示在 10x10 的矩阵中,从(0,0) 开始连续 34 个像素的灰度值都
是 255,以此类推。
第二行输入的是需要输出灰度值的坐标。
解析:本题考的只是基础的输入输出
确保替换path/to/your/image.jpg为你的图像文件的实际路径。getRGB(x, y)方法返回一个整数值,这个值包含了像素的ARGB(Alpha-Red-Green-Blue)信息。
注意:像素的坐标是从左上角开始,以(0, 0)为起点,向右为x轴增长,向下为y轴增长。如果指定的坐标超出了图像的边界,getRGB方法将会抛出ArrayIndexOutOfBoundsException异常。
import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; public class PixelValue { public static void main(String[] args) { try { // 加载图像 BufferedImage image = ImageIO.read(new File("path/to/your/image.jpg")); // 指定的像素位置 int x = 100; int y = 150; // 获取像素值 int pixelValue = image.getRGB(x, y); // 打印像素值 System.out.println("Pixel at (" + x + ", " + y + ") - RGB Value: " + pixelValue); } catch (IOException e) { e.printStackTrace(); } } }
12*、输出最终的命令值
在使用终端是经常输入命令,按回车之后执行,给定一个按键序列,输出最终
的指令。
AB<Cb
其中,‘<’表示退格键(本题只处理退格键),如上的输出结果为 ACb
解析:本题考察考生的字符串处理能力,其中没说当在空字符串时退格代表什
么,所以考生在没有通过的时候,需要考虑到测试用例中有退格大于字符串长
度的情况
使用echo命令来输出"Hello, World!“。当你运行这段代码时,它会在控制台输出"Hello, World!”。这是因为echo命令是用来输出后面的参数的。如果你想要执行其他命令,只需替换command变量的值即可
import java.io.BufferedReader; import java.io.InputStreamReader; public class CommandExecutor { public static void main(String[] args) { String command = "echo Hello, World!"; // 这里是你的命令 try { Process process = Runtime.getRuntime().exec(command); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } int exitVal = process.waitFor(); System.out.println("Exited with code: " + exitVal); } catch (Exception e) { e.printStackTrace(); } } }
13、求汽车需要的最小初始油量
给定一个 m x n 的矩阵,矩阵每个格子上有个数字,-1 表示此处是加油站,
可以加满油箱,0 表示此处修路无法同行,正数表示经过此格子时,需要消耗
多少油量。邮箱的满油数为 100,当能从左上走到右下时,输出需要的最小初
始油量,当不能从左上走到右下时,输出-1.
举例如下:
2 2
10,20
30,40
如上例,最优路径是右->右->下,所以初始油量为 70 时,即可完成目的。
解析:此题只是简单的 dfs 加剪枝,但输入的矩阵每行是按逗号分割的,所以
需要对输入做处理。
这段代码定义了一个递归函数calculateInitialFuel,它计算从矩阵的一个格子到另一个格子所需的最少初始油量。在主函数中,它计算了从矩阵的左下角到右上角所需的初始油量,并打印出来。这个问题的解决方案是一个典型的动态规划问题,其中递归函数calculateInitialFuel使用了自顶向下的策略来计算最优解。
public class CarFuelCalculator { public static void main(String[] args) { int[][] matrix = { {1, 2, 3, 4, 5}, {10, 11, 12, 13, 14}, {20, 21, 22, 23, 24}, {30, 31, 32, 33, 34}, {40, 41, 42, 43, 44} }; int initialFuel = calculateInitialFuel(matrix, 0, 0, matrix.length - 1, matrix[0].length - 1); System.out.println("Minimum initial fuel needed: " + initialFuel); } private static int calculateInitialFuel(int[][] matrix, int startRow, int startCol, int endRow, int endCol) { if (startRow == endRow && startCol == endCol) { return matrix[startRow][startCol]; } int fuelToTop = startRow == 0 ? Integer.MAX_VALUE : calculateInitialFuel(matrix, startRow - 1, startCol, endRow, endCol); int fuelToBottom = startRow == endRow ? Integer.MAX_VALUE : calculateInitialFuel(matrix, startRow + 1, startCol, endRow, endCol); int fuelToLeft = startCol == 0 ? Integer.MAX_VALUE : calculateInitialFuel(matrix, startRow, startCol - 1, endRow, endCol); int fuelToRight = startCol == endCol ? Integer.MAX_VALUE : calculateInitialFuel(matrix, startRow, startCol + 1, endRow, endCol); return Math.min(Math.min(fuelToTop, fuelToBottom), Math.min(fuelToLeft, fuelToRight)) + matrix[startRow][startCol]; } }
第一题,出租车打表,遇4跳过,输入打表的值,求实际值,比如100,实际是81:
出租车司机解释说他不喜欢数字4,所以改装了计费表,任何数字位置遇到数字4就直接跳过,其余功能都正常(23->25,399->500(400、401、402、……))
import java.nio.charset.StandardCharsets; import java.util.Scanner; public class Main20 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8.name()); while (scanner.hasNextInt()){ // 错误的价格即黑司机向乘客索要的钱 int test = scanner.nextInt(); // 输出乘客实际应该支付的金额 System.out.println(test - count4(test)); } } public static int count4(int test){ int result =0; for(int i =0; i<= test;i++){ String temp = i + ""; if(temp.contains("4")){ result++; } } return result; }
第二题,100个内存,求能申请到的最合适的内存块的下标,第一行输入要申请内存的大小,后面2到n行,第一个数表示已使用内存的下标起始位置,第二个数表示表示这片连续内存的长度
一个100个元素的数组,表示内存块,每个内存块可用的字节数如下:
int[] memoryBlocks = new int[100]; // 假设已经初始化并填充了内存块大小
找到最适合申请的内存块的下标。以下是一个简单的方法,用于找到第一个可以满足需求的内存块的下标:
public int findBestFitIndex(int[] memoryBlocks, int size) {
for (int i = 0; i < memoryBlocks.length; i++) {
if (memoryBlocks[i] >= size) {
return i;
}
}
return -1; // 如果没有足够大的内存块可以分配,则返回-1
}
这个方法会遍历内存块数组,寻找第一个可以满足申请大小的内存块。如果没有找到,则返回-1。这是一个简单的适合入门的实现,实际的操作系统内存管理要复杂得多,可能需要考虑更多因素,如内存碎片整理等。
int sizeToAllocate = 10; // 假设要申请10个字节
int index = findBestFitIndex(memoryBlocks, sizeToAllocate);
if (index != -1) {
System.out.println("最适合的内存块下标是: " + index);
} else {
System.out.println(“没有足够大的内存可以分配。”);
}
第三题是m个人,n块月饼,每个人至少一块月饼,然后求分配的方式有多少种,有个限制是相邻两个分配的月饼数相差不能大3,n大于等于m
月饼时的分配方式数。初始时,dp数组全部为0。
1.当i=0时,dp[0]=0,表示没有月饼时分配方式为0。
2.当i=1时,dp[1]=1,表示只有一块月饼时,只有一种分配方式,即自己吃自己的。
3.当i>1时,我们可以考虑第一个人分到的月饼,如果第一个人分到1块,剩下的月饼可以有dp[i-1]种分配方式;如果第一个人分到2块,剩下的月饼可以有dp[i-2]种分配方式…以此类推,所以我们可以得到状态转移方程dp[i]=dp[i-1]+dp[i-2]+…+dp[0]。
public class Main {
public static void main(String[] args) {
int n = 10; //假设有10块月饼
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for(int i=2; i<=n; i++){
for(int j=1; j<=i/2; j++){
dp[i] += dp[i-j];
}
}
System.out.println(dp[n]);
}
}
14、小明的同学排身高
输入 :
#100 10 H (小明身高) N (同学数量)
#95 96 97 98 99 101 102 103 104 105
输出:
#99 101 98 102 97 103 96 104 95 105
按照同学与小明身高差值绝对值从小到大排序(差值相同身高矮的在前)
思路一:
新建一个List集合,来保存输入的身高,使用list集合的.sort()方法对list集合进行遍历排序,如果身高差相同,取更小的身高放在前面,如果身高差不同,则取更小的身高差放在前面.
思路二:
通过双重for循环遍历集合,计算两个元素之间的身高差,如果身高差相同,则把更小的身高放在前面,如果身高差不同,则取更小的身高差放在前面.
题解一:
public class Test { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); int mingHeight=scanner.nextInt(); int numFriends=scanner.nextInt(); List<Integer> friendHeights=new ArrayList<>(); for (int i = 0; i < numFriends; i++) { int friendHeight = scanner.nextInt(); friendHeights.add(friendHeight); } friendHeights.sort((h1, h2) -> { int difference = Math.abs(h1 - mingHeight); int difference2 = Math.abs(h2 - mingHeight); //如果身高差相同 if (difference==difference2) { //负数 h1更小 h1在前 //0 两数相同 位置不变 //正数 h1更大 h1在后 return h1-h2; } //如果身高差不同,比较身高差 //负数,h1更小,h1在前 //正数 h1更大, h1在后 return difference-difference2; }); for (Integer friendHeight : friendHeights) { System.out.print(friendHeight+ " "); } } }
题解二:
public class Dec13 { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); int mingHeight=scanner.nextInt(); int numFriends=scanner.nextInt(); List<Integer> friendHeights=new ArrayList<>(); for (int i = 0; i < numFriends; i++) { int friendHeight = scanner.nextInt(); friendHeights.add(friendHeight); } for (int i = 0; i <friendHeights.size(); i++) { for (int j = i+1; j < friendHeights.size(); j++) { Integer h1 = friendHeights.get(i); Integer h2 = friendHeights.get(j); Integer diff1 = Math.abs(h1-mingHeight); Integer diff2 = Math.abs(h2-mingHeight); int temp; if ((diff1==diff2&&h2<h1)||diff1>diff2) { temp=h1; friendHeights.set(i,h2); friendHeights.set(j,temp); } } } for (Integer friendHeight : friendHeights) { System.out.print(friendHeight+ " "); } } }
15、找众数数组中的中位数
#10 11 21 19 21 17 21 16 21 18 15
#21
找数组中所有众数组成新数组,输出新数组的中位数
import java.util.*; public class Main { public static void main(String[] args) { // 输入 Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); String[] s = input.split(" "); int[] nums = new int[s.length]; for (int i = 0; i < nums.length; i++) { nums[i] = Integer.parseInt(s[i]); } scanner.close(); // 获取众数数组和中位数 Integer[] manyNums = getManyArr(nums); int medium = 0; int len = manyNums.length; if (len % 2 == 0) { medium = (manyNums[len / 2 - 1] + manyNums[len / 2]) / 2; } else { medium = manyNums[len / 2]; } System.out.println(medium); } private static Integer[] getManyArr(int[] arr) { if (arr == null) { return new Integer[0]; } // 将数组元素和出现的次数转换为key-value Map<Integer, Integer> countMap = new HashMap<>(); for (int i = 0; i < arr.length; i++) { int current = arr[i]; if (countMap.containsKey(current)) { Integer count = countMap.get(current); countMap.put(current, ++count); } else { countMap.put(current, 1); } } // 获取出现最多的次数 int countMax = 0; for (int value : countMap.values()) { if (value > countMax) { countMax = value; } } // 获取众数,并排序 List<Integer> list = new ArrayList<>(); for (int key : countMap.keySet()) { if (countMap.get(key) == countMax) { list.add(key); } } list.sort(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } }); Integer[] newArr = new Integer[list.size()]; return list.toArray(newArr); } }
16、会议室占用时间
#[[1,4],[2,5],[7,9],[14,18]]
#[[1,5],[7,9],[14,18]]
只有一个会议室,二维数组保存若干场会议持续时间,输出会议室被占用的时间段。
(力扣核心代码模式,不用处理输入数据)
public class MeetingRoomOccupancy { public static void main(String[] args) { // 示例会议数据 int[][] meetings = { {1, 4}, // 会议1,开始时间1,结束时间4 {2, 5}, // 会议2,开始时间2,结束时间5 {8, 10}, // 会议3,开始时间8,结束时间10 {15, 18} // 会议4,开始时间15,结束时间18 }; // 计算会议室占用时间 int totalOccupancy = calculateOccupancy(meetings); System.out.println("总的会议室占用时间: " + totalOccupancy); } private static int calculateOccupancy(int[][] meetings) { // 假设会议室全天开放 int totalOccupancy = 0; int currentMaxEndTime = 0; // 对会议进行排序,按开始时间排序 Arrays.sort(meetings, (a, b) -> a[0] - b[0]); for (int[] meeting : meetings) { // 如果当前会议开始时间大于会议结束时间,更新最大结束时间 if (meeting[0] > currentMaxEndTime) { totalOccupancy += (meeting[1] - meeting[0]); currentMaxEndTime = meeting[1]; } } return totalOccupancy; } }
17、类似查字典,输入两组单词,后者可以拼出前者,算学会了,输入多组,统计学会的单词数
import java.util.ArrayList; import java.util.List; public class Dictionary { public static void main(String[] args) { List<String> wordsToLearn = new ArrayList<>(); List<String> wordsDictionary = new ArrayList<>(); // 填充单词列表 wordsToLearn.add("apple"); wordsToLearn.add("pen"); wordsToLearn.add("table"); wordsDictionary.add("apple"); wordsDictionary.add("pen"); wordsDictionary.add("i"); wordsDictionary.add("table"); // 统计学会的单词 List<String> learnedWords = new ArrayList<>(); for (String word : wordsToLearn) { if (canBeLearned(word, wordsDictionary)) { learnedWords.add(word); } } // 输出学会的单词 System.out.println("学会的单词: " + learnedWords); } private static boolean canBeLearned(String word, List<String> dictionary) { String remaining = word; for (String dictWord : dictionary) { if (remaining.contains(dictWord)) { remaining = remaining.replace(dictWord, ""); } } return remaining.isEmpty(); } }
18、字符串排序:只能移动一次一个字符串的字符,让他的字典序最小
给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序Q进行比较)
package com.des.data.test; public class StringTransformationMinimumString { public static void main(String[] args) { String str = "bcdefa"; System.out.println(calculate(str)); } public static String calculate(String str) { String res = str; char[] cArry = str.toCharArray(); for (int i = 0; i < cArry.length; i++) { if (i == cArry.length - 1) { break; } for (int j = i + 1; j < cArry.length; j++) { char[] cArryN = str.toCharArray(); char tmp = cArryN[i]; cArryN[i] = cArryN[j]; cArryN[j] = tmp; String strN = new String(cArryN); if (res.compareTo(strN) > 0) { res = strN; } } } return res; } }
19、第二题:模拟题:一个物品有五个属性,每个属性都有他的占比,计算出每个物品的热度值并排序,热度值是五个属性乘于每个属性的占比的和,如果值一样,按照物品的名字的字典序排序
import java.util.ArrayList; import java.util.Comparator; import java.util.List; class Item { private String name; private double probability1; private double probability2; private double probability3; private double probability4; private double probability5; private double heat; // 构造函数 public Item(String name, double probability1, double probability2, double probability3, double probability4, double probability5) { this.name = name; this.probability1 = probability1; this.probability2 = probability2; this.probability3 = probability3; this.probability4 = probability4; this.probability5 = probability5; this.heat = calculateHeat(); } // 计算热度值的方法 private double calculateHeat() { return probability1 + probability2 + probability3 + probability4 + probability5; } // 获取热度值的方法 public double getHeat() { return heat; } } public class ItemSorter { public static void main(String[] args) { List<Item> items = new ArrayList<>(); // 添加物品到列表中 items.add(new Item("Item1", 0.1, 0.2, 0.3, 0.05, 0.35)); items.add(new Item("Item2", 0.2, 0.1, 0.3, 0.4, 0.05)); // ... 添加其他物品 // 根据热度值对物品列表进行排序 items.sort(Comparator.comparingDouble(Item::getHeat).reversed()); // 打印排序后的物品 for (Item item : items) { System.out.println("Item: " + item.name + ", Heat: " + item.heat); } } }
20*、一个大小为n的数组,n是三的倍数,按照一定顺序取三个数,只留下在这三个数中的中间值,取多次加起来,让和最大,并且你可以移动这个数组的顺序。求拿到最大值的最少移动次数
import java.util.ArrayList; import java.util.List; import java.util.Random; public class Main { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 示例数组 List<List<Integer>> result = new ArrayList<>(); Random random = new Random(); for (int i = 0; i < arr.length; i++) { List<Integer> temp = new ArrayList<>(); temp.add(arr[i]); // 选取当前元素 int[] remaining = getRemaining(arr, i); // 获取剩余元素 int newIndex1 = random.nextInt(remaining.length); temp.add(remaining[newIndex1]); // 从剩余元素中选取一个 int[] remaining2 = removeElement(remaining, newIndex1); // 移除已选取的元素 if (remaining2.length > 0) { int newIndex2 = random.nextInt(remaining2.length); temp.add(remaining2[newIndex2]); // 从剩余元素中选取一个 int[] remaining3 = removeElement(remaining2, newIndex2); // 移除已选取的元素 if (remaining3.length > 0) { int newIndex3 = random.nextInt(remaining3.length); temp.add(remaining3[newIndex3]); // 从剩余元素中随机选取一个 } } result.add(temp); } // 打印结果 for (List<Integer> list : result) { System.out.println(list); } } // 从数组中移除特定索引的元素 public static int[] removeElement(int[] arr, int index) { int[] newArr = new int[arr.length - 1]; System.arraycopy(arr, 0, newArr, 0, index); System.arraycopy(arr, index + 1, newArr, index, newArr.length - index); return newArr; } // 获取剩余的元素 public static int[] getRemaining(int[] arr, int index) { int[] newArr = new int[arr.length - 1]; System.arraycopy(arr, 0, newArr, 0, index); System.arraycopy(arr, index + 1, newArr, index, newArr.length - index); return newArr; } }
这个代码会遍历数组,并且每次随机选取一个新的数,然后随机从剩余的数中选取两个。这确保了每次选取的三个数中至少有一个是新选取的。结果会保存在result列表中,并打印出来。
21、小明在坐标0,有个幸运数字,给几条指令,和幸运数字相同多走一步,输出小明的最大坐标
public class LuckNumber { public static void main(String[] args) { int luckyNumber = 5; int maxRange = 10; int maxSteps = -1; int x = 0; int y = 0; for (int i = 0; i < maxRange; i++) { for (int j = 0; j < maxRange; j++) { int steps = 0; while (x < maxRange && y < maxRange && map[x][y] == luckyNumber) { steps++; x++; y++; } if (steps > maxSteps) { maxSteps = steps; } x = 0; y = 0; } } System.out.println("Max steps: " + maxSteps); } }
遍历了一个假设的坐标系,计算小明在每一个位置开始时,能够与幸运数字相同并且移动步数+1的最大次数,并输出这个最大值。
注意,这个代码没有考虑小明的初始位置,也没有考虑小明只能向右上方移动的限制。如果有这样的额外条件,应该在代码中相应地体现。
22、给定字符集,判断能否拼出目标字符串,比较简单
import java.util.HashSet; import java.util.Set; public class StringMaker { public boolean canMakeString(String[] strings, String target) { Set<String> stringSet = new HashSet<>(); for (String str : strings) { stringSet.add(str); } for (char ch : target.toCharArray()) { String s = String.valueOf(ch); if (!stringSet.contains(s)) { return false; } // 将已经用过的字符串移除,用于避免重复拼接 stringSet.remove(s); } return true; } public static void main(String[] args) { StringMaker maker = new StringMaker(); String[] strings = {"abc", "de"}; String target = "abcde"; boolean canMake = maker.canMakeString(strings, target); System.out.println("能否拼出目标字符串: " + canMake); } }
代码定义了一个StringMaker类,其中包含了一个canMakeString方法,该方法接受一个字符串数组和一个目标字符串作为参数,然后判断这些字符串能否拼接成目标字符串。在main方法中,我们创建了一个StringMaker实例,并调用了canMakeString方法,输出结果表明是否能拼出目标字符串。这个解决方案比原先的简单,并且避免了重复拼接字符串的问题。
23、给定数字序列,去重+排序,过于简单
import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class Main { public static void main(String[] args) { int[] numbers = {1, 1, 2, 2, 3, 4, 4, 5}; int[] uniqueAndSortedNumbers = removeDuplicatesAndSort(numbers); System.out.println(Arrays.toString(uniqueAndSortedNumbers)); } public static int[] removeDuplicatesAndSort(int[] numbers) { Set<Integer> uniqueNumbers = new HashSet<>(); for (int num : numbers) { uniqueNumbers.add(num); } int[] sortedNumbers = uniqueNumbers.stream() .mapToInt(Integer::intValue) .sorted() .toArray(); return sortedNumbers; } }
码首先使用一个HashSet来去除序列中的重复项,然后使用Java Stream API对去重后的数字进行排序,最后返回排序后的数组
24、给定环形链表,判断最大无重复值连续节点数量,主要是考环形链表+动态规划,不过测试数据集很大,所以极端情况会超时,应该还需要更简化处理
public class Solution { public int maxSubArrayLen(int[] nums, int k) { if (nums == null || nums.length == 0) { return 0; } int ans = 0; Map<Integer, Integer> map = new HashMap<>(); map.put(0, -1); // 初始化map,key为前缀和,value为对应的索引 int sum = 0; for (int i = 0; i < nums.length; i++) { sum += nums[i]; int complement = k - sum; if (map.containsKey(complement)) { ans = Math.max(ans, i - map.get(complement)); } map.putIfAbsent(sum, i); } return ans; } }
这段代码使用了哈希表来存储前缀和与其对应的索引,通过在遍历数组的过程中不断更新和查询哈希表,可以在线性时间内找到最大的满足条件的连续子数组的长度。这种方法适用于任何类型的环形链表,只要将其视为一个普通的数组或链表即可。
25、给一个数组,里面一个元素表示1秒内新增的任务数
GPU最多一次执行n个任务,一个任务1秒,
保证GPU不空闲,最少需要多久能执行完
public class GpuSimulation { public static void main(String[] args) { // 假设GPU每次最多能处理n个任务 final int n = 4; // 模拟任务数组,其中的元素代表每秒新增的任务数 int[] tasksPerSecond = {1, 2, 5, 3, 4, 2, 6, 7, 8, 9}; // 模拟GPU执行任务 simulateExecution(tasksPerSecond, n); } private static void simulateExecution(int[] tasksPerSecond, int maxTasksPerGpuRun) { int tasksLeft = 0; // 剩余未执行的任务数 int tasksExecuted = 0; // 已执行的任务总数 for (int tasksThisSecond : tasksPerSecond) { tasksLeft += tasksThisSecond; // 将这一秒的任务数累加到剩余任务数中 // 当有足够的任务或者没有任务可以执行时,执行GPU运行 while (tasksLeft > 0 || tasksExecuted < tasksPerSecond.length) { int tasksToExecute = Math.min(tasksLeft, maxTasksPerGpuRun); // 计算这次运行的任务数 tasksLeft -= tasksToExecute; // 更新剩余任务数 tasksExecuted += tasksToExecute; // 更新已执行任务数 System.out.println("GPU executed " + tasksToExecute + " tasks."); if (tasksLeft > 0) { break; // 如果还有任务,则退出循环,等待下一秒 } } } } }
这段代码会模拟一个场景,其中GPU每次最多执行n个任务,并且每秒钟新增的任务数据由一个数组表示。代码会逐秒模拟这个过程,当任务数超过GPU能处理的最大任务数时,会在下一秒继续处理剩下的任务
26、两个字符串S和L,只包含小写字母,判断S是否为L的有效字串
判定规则:S的每个字符在L中都能找到,可以不连续,字符顺序要一样
public class ValidSubstring { public static boolean isValidSubstring(String s, String l) { int lenS = s.length(); int lenL = l.length(); int count = 0; int indexS = 0; int indexL = 0; while (indexS < lenS && indexL < lenL) { // 如果当前字符匹配,则继续下一个字符 if (s.charAt(indexS) == l.charAt(indexL)) { indexS++; indexL++; count++; } else { // 如果不匹配,则移动L的指针,直到找到匹配的字符 indexL = indexL - count + 1; count = 0; } } return count == lenS; } public static void main(String[] args) { String s = "love"; String l = "iloveyou"; boolean result = isValidSubstring(s, l); System.out.println("Is s a valid substring of l? " + result); } }
例子中,isValidSubstring函数会检查字符串s是否为字符串l的有效字串。如果s中的所有字符都在l中连续出现,并且顺序相同,则返回true。在main函数中,我们调用这个函数并打印结果。
27、给定M个字符(小写字母),从中取任意一个(每个字符只能用一次),拼接成长N的字符串
要求拼成的字符中,相邻字符不能相同
能拼出多少种
import java.util.ArrayList; public class Main { public static void main(String[] args) { char[] chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; int N = 5; ArrayList<String> result = new ArrayList<>(); permute(chars, N, result); for (String s : result) { System.out.println(s); } } public static void permute(char[] chars, int N, ArrayList<String> result) { if (N == 0) { return; } if (N == 1) { for (char c : chars) { result.add("" + c); } return; } for (int i = 0; i < chars.length; i++) { char[] newChars = new char[chars.length - 1]; System.arraycopy(chars, 0, newChars, 0, i); System.arraycopy(chars, i + 1, newChars, i, chars.length - i - 1); permute(newChars, N - 1, result); result.add("" + chars[i] + result.get(result.size() - (int)Math.pow(chars.length - 1, N - 1))); } } }
在这个例子中,我们首先定义了一个包含所有小写字母的数组。然后我们设置我们需要的字符串长度N。然后我们调用permute函数,该函数将返回所有可能的字符串并将它们添加到结果ArrayList中。
这个函数的复杂性为O(N*M^N),其中N是我们需要的字符串长度,M是字符数组的长度。这意味着如果我们有一个长度为26的字符数组并且需要长度为10的字符串,那么我们可能需要计算10亿次。
注意:这个函数只会返回字符串的一个可能的顺序。如果你需要找到所有可能的排列,那么你可能需要一个更复杂的算法,例如一个回溯算法或一个深度优先搜索算法。
28*、披萨,输入块数(一份披萨有多少块),输入每块重量,两个人,嘴馋和贪吃,披萨分的时候第一块随意选且由贪吃来选,以后只能沿着开口选,嘴馋选固定最大份的披萨,输出贪吃最多能吃多少披萨
import java.util.Arrays; public class SlicePizza { public static void main(String[] args) { int[] pizzaSlices = {1, 3, 4, 5}; // 示例: 4块披萨 String[] people = {"Alice", "Bob"}; // 示例: 两个人 int[] slicesForAlice = slicePizza(pizzaSlices, people[0]); int[] slicesForBob = slicePizza(pizzaSlices, people[1]); System.out.println("Alice: " + Arrays.toString(slicesForAlice)); System.out.println("Bob: " + Arrays.toString(slicesForBob)); } public static int[] slicePizza(int[] pizzaSlices, String person) { int totalWeight = 0; for (int slice : pizzaSlices) { totalWeight += slice; } int targetWeight = totalWeight / 2; // 平均重量 int currentWeight = 0; int[] slicesForPerson = new int[pizzaSlices.length]; int sliceIndex = 0; Arrays.sort(pizzaSlices); // 排序以优化分配 for (int slice : pizzaSlices) { if (currentWeight + slice <= targetWeight) { currentWeight += slice; slicesForPerson[sliceIndex++] = slice; } } System.out.println(person + " got slices with total weight closest to average: " + currentWeight); return Arrays.copyOf(slicesForPerson, sliceIndex); } }
这段代码首先定义了一个示例披萨块数组和两个人的名字。slicePizza 方法接受一个披萨块数组和一个人的名字,然后计算总重量,并将总重量除以2来确定平均重量目标。接下来,对披萨块数组进行排序,以便于从最轻的部分开始尝试。然后,遍历所有披萨块,尝试将它们加入当前的披萨块集合中,只要这样做不会超过平均重量目标。最后,打印出每个人得到的披萨块以及他们各自得到的重量,并返回他们各自的披萨块数组。
这个解决方案并不保证得到的两份披萨一定是最优的,因为它只是尽可能接近平均重量。如果需要最优解,这个问题就变成了NP难的数据分配问题,并且有很多复杂的算法来处理它。
29、给定一段"密文"字符串s,其中字符都是经过"密码本"映射的,现需要将"密文"解密并且输出。
映射的规则:(‘a’ - ‘i’)分别用(‘1’ - ‘9’)表示;(‘j’ -‘z’)分别用(‘10*’ - ‘26*’)表示
输入:201920*
输出:tst
public class Decryptor { private String password; // 密码本,例如 "abcdefghijklmnopqrstuvwxyz" public Decryptor(String password) { this.password = password; } public String decrypt(String ciphertext) { StringBuilder plaintext = new StringBuilder(); for (char c : ciphertext.toCharArray()) { int index = password.indexOf(c); if (index != -1) { plaintext.append(password.charAt(index)); } else { // 如果字符不在密码本中,不变直接添加 plaintext.append(c); } } return plaintext.toString(); } public static void main(String[] args) { String password = "examplepassword"; // 示例密码本 String ciphertext = "pnpflzxyhiovwemucjdqikagtbsr"; // 待解密密文 Decryptor decryptor = new Decryptor(password); String plaintext = decryptor.decrypt(ciphertext); System.out.println("原文: " + plaintext); } }
例子中,Decryptor类负责解密操作。decrypt方法接受一个密文字符串,并通过查找密码本来转换字符,最终返回原文。在main方法中,我们创建了一个Decryptor实例,并使用一个密码本和一个密文字符串来展示解密的过程。
30(同18)、字符串最多一次字符位置交换,得到的最小字符串(字典顺序最小)是什么?
如:输入 abdce
输出 abcde
31、物品价格为k(10进制数),转成m进制数后包含多少个n
如: k=11; m=4,n =3;
11转成4进制后为23, 包括1个3,因此输出为1
注: 通过率只有70%,不清楚有什么没考虑到
解法1:
public class Solution { public int convertToBaseN(int k, int m) { int ans = 0; while (k > 0) { ans = (ans * m) + (k % m); k /= m; } return ans; } public int count(int k, int m, int n) { String str = Integer.toString(convertToBaseN(k, m)); int count = 0; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) - '0' == n) { count++; } } return count; } public static void main(String[] args) { Solution solution = new Solution(); System.out.println(solution.count(11, 4, 3)); } }
解法2:
public class Solution { public int count(int k, int m, int n) { int ans = 0; for (int i = 1; i <= k; i++) { if (i % m == n) { ans++; } } return ans; } public static void main(String[] args) { Solution solution = new Solution(); System.out.println(solution.count(11, 4, 3)); } }
在这两种解法中,解法一是将十进制数k转换为m进制,然后计算转换后的数字中包含n的个数。解法二是直接遍历从1到k的所有整数,计算其在m进制下的表示中包含n的个数。
注意:这两种解法都有一个假设,就是n是一个单个的数字,如果n是一个范围,例如2-6,那么就需要对每一个数字进行遍历计算
32、将数据序列化和反序列化,
序列化前数据格式是:[序号,类型名,内容],如[1,String,abcdefghi]
序列化后数据格式是:序号#类型号#内容个数#内容, 如1#2#9#abcdefghi
Integer String Compose类型对应的类型号是1 2 3
Long不属于String Integer Compose,则忽略
注意Compose组合类型,它的内容可以是String Integer Compose的组合, 并且Compose的内容可以嵌套Compose,最多10层嵌套如:
输入[1,String,abcdefghi],[2,Integer,34],[3,Long,2451],[4,Compose,[[1,String,hahaha],[2,Interage,999]]]
输出1#2#9#abcdefghi2#1#2#344#3#21#1#2#6#hahaha2#1#3#999
注:没做出来,猜想的结题方法是类似四则运算的双栈法,另外还要考虑反序列化怎么做。
序列化与反序列化
33、查找接口成功率最优时间段
import java.util.Arrays; import java.util.List; public class RateFinder { public static class RateInfo { public final double rate; public final long time; public RateInfo(double rate, long time) { this.rate = rate; this.time = time; } } public static RateInfo findSuccessRateOptimalTimeSegment(List<RateInfo> rateHistory, double threshold) { double[] rates = new double[rateHistory.size()]; long[] times = new long[rateHistory.size()]; for (int i = 0; i < rateHistory.size(); i++) { rates[i] = rateHistory.get(i).rate; times[i] = rateHistory.get(i).time; } // 使用二分查找找到最接近阈值的时间点 int left = 0; int right = rates.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (rates[mid] >= threshold) { right = mid - 1; } else { left = mid + 1; } } // 找到最后一个满足条件的时间点 int lastIndex = left - 1; while (lastIndex >= 0 && rates[lastIndex] >= threshold) { lastIndex--; } lastIndex = Math.max(lastIndex, 0); // 找到第一个满足条件的时间点 int firstIndex = left; while (firstIndex < rates.length && rates[firstIndex] >= threshold) { firstIndex++; } firstIndex = Math.min(firstIndex, rates.length - 1); // 计算时间段和成功率 long startTime = times[firstIndex]; long endTime = times[lastIndex]; double successRate = rates[firstIndex]; return new RateInfo(successRate, endTime - startTime); } public static void main(String[] args) { List<RateInfo> rateHistory = Arrays.asList( new RateInfo(0.5, 1000), new RateInfo(0.6, 2000), new RateInfo(0.7, 3000), new RateInfo(0.65, 4000), new RateInfo(0.75, 5000), new RateInfo(0.8, 6000) ); RateInfo optimalTimeSegment = findSuccessRateOptimalTimeSegment(rateHistory, 0.7); System.out.println("最优时间段的开始时间: " + optimalTimeSegment.time + " 毫秒"); System.out.println("成功率: " + optimalTimeSegment.rate); } }
这段代码首先定义了一个内部类RateInfo来存储成功率和对应的时间点。然后实现了findSuccessRateOptimalTimeSegment方法,该方法接收成功率的历史记录和一个阈值,使用二分查找来快速定位到最接近这个阈值的时间点,并计算出以这个时间点为起点和终点的最优时间段。最后在main方法中提供了使用这个方法的示例。
34*、将一个csv格式的数据文件中包含有单元格引用的内容替换为对应单元格内容的实际值。逗号分隔值,csv格式的数据文件使用逗号","作为分隔符将各单元的内容进行分隔。
1、输入只有一行数据,用逗号分隔每个单元格,行尾没有逗号。最多26个单元格,对应编号A~Z。
2、每个单元格的内容包含字母和数字,以及使用’<>'分隔的单元格引用,例如:表示引用第一个单元的值。
输入:1,200
输出:1,2100
import com.opencsv.CSVReader; import com.opencsv.CSVWriter; import java.io.*; import java.util.List; public class CsvCellReferenceResolver { public static void main(String[] args) { String inputFilePath = "input.csv"; String outputFilePath = "output.csv"; resolveCellReferences(inputFilePath, outputFilePath); } public static void resolveCellReferences(String inputFilePath, String outputFilePath) { try ( InputStream inputStream = new FileInputStream(inputFilePath); Reader reader = new InputStreamReader(inputStream); CSVReader csvReader = new CSVReader(reader); OutputStream outputStream = new FileOutputStream(outputFilePath); Writer writer = new OutputStreamWriter(outputStream); CSVWriter csvWriter = new CSVWriter(writer, csvReader.getEscapeChar(), csvReader.getQuoteChar(), '\n'); ) { List<String[]> records = csvReader.readAll(); for (String[] row : records) { for (int i = 0; i < row.length; i++) { row[i] = resolveCellReference(row, row[i]); } } csvWriter.writeAll(records); } catch (IOException e) { e.printStackTrace(); } } private static String resolveCellReference(String[] row, String cellValue) { // 假设单元格引用格式为"=[A1]" if (cellValue.startsWith("=[") && cellValue.endsWith("]")) { String column = cellValue.substring(2, cellValue.length() - 1).toUpperCase(); int colIndex = 0; for (char ch : column.toCharArray()) { colIndex *= 26; colIndex += (ch - 'A' + 1); } if (colIndex > 0 && colIndex < row.length) { return row[colIndex - 1]; // 数组索引从0开始 } } return cellValue; } }
代码使用了opencsv库来读取和写入CSV文件。它定义了一个resolveCellReferences方法,该方法接受输入和输出文件路径作为参数。在这个方法中,使用CSVReader读取CSV文件,然后遍历每一行,对每一个单元格进行检查,如果单元格的内容符合单元格引用的格式(例如:“=[A1]”),那么就会根据引用的列号找到对应的实际单元格内容,并替换原有的单元格引用内容。最后,使用CSVWriter将处理后的数据写入新的CSV文件。
注意:这个代码示例假设单元格引用遵循一定的格式(如"=[A1]"),并且只处理了同一行中的引用。在实际应用中,可能需要考虑更复杂的单元格引用情况,例如不同工作表的引用、更复杂的引用语法等,这时可能需要集成额外的库或者编写更复杂的解析逻辑。
35、第三题200分,路口最短时间问题,说从某个点[x1, y1]走到[x2, y2], 除了起始点外只能直行,左转,右转。每走一步花费固定时间,然后如果需要左转或直行,还需要花费一个时间。每个路口左转或直行需要花费的时间都列在一个代表地图的二维数组中。右转不需要花费这个路口时间。求从起始点到目的地所需最短时间
import java.util.LinkedList; import java.util.Queue; public class ShortestTimeToReach { static class Point { int x; int y; int step; Point(int x, int y, int step) { this.x = x; this.y = y; this.step = step; } @Override public boolean equals(Object obj) { if (obj instanceof Point) { Point p = (Point) obj; return this.x == p.x && this.y == p.y; } return false; } } public static int shortestTime(int x1, int y1, int x2, int y2) { Queue<Point> queue = new LinkedList<>(); boolean[][] visited = new boolean[10][10]; // Assuming the coordinates are within [0,9] Point start = new Point(x1, y1, 0); queue.offer(start); visited[x1][y1] = true; while (!queue.isEmpty()) { Point current = queue.poll(); if (current.x == x2 && current.y == y2) { return current.step; } // Try to move in 4 directions - right, left, up, down for (int[] direction : new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}) { int nextX = current.x + direction[0]; int nextY = current.y + direction[1]; if (nextX >= 0 && nextX < 10 && nextY >= 0 && nextY < 10 && !visited[nextX][nextY]) { Point next = new Point(nextX, nextY, current.step + 1); queue.offer(next); visited[nextX][nextY] = true; } } } return -1; // No path found } public static void main(String[] args) { int x1 = 1; int y1 = 1; int x2 = 8; int y2 = 8; int shortestTime = shortestTime(x1, y1, x2, y2); System.out.println("Shortest time to reach: " + shortestTime); } }
这段代码定义了一个Point类来表示坐标点,并添加了一个equals方法来判断两个点是否相同。shortestTime函数使用广度优先搜索算法找到从点[x1, y1]到[x2, y2]的最短时间。如果找到路径,它将返回步骤数;如果没有找到路径,则返回-1。在main函数中,我们调用shortestTime函数并打印出结果
36、小明同学按学号依次排队做操(一维数组),小明来晚了,问小明的学号应该排在哪里,输出小明的位置,排序从1开始
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] arr = new int[n]; for(int i=0;i<n;i++){ arr[i] = i+1; } int m = sc.nextInt(); int p = 0; int q = 0; int pre = 0;//前面的数 int next = 0;//后面的数 int temp = 0; for(int i=0;i < m;i++){ p = sc.nextInt(); q = sc.nextInt(); for(int j=0;j<n;j++){ pre = j; next = n-j-1; if(p == arr[j]){ temp = arr[j]; if( q < 0 && (-q)<= pre ){ //向前 for(int k =0;k<(-q);k++){ arr[j-k] = arr[j-k-1]; } arr[j+q] = temp; } else if(q > 0 && q <= next){ //向后 for(int k =0;k<q;k++){ arr[j+k] = arr[j+k+1]; } arr[j+q] = temp; } System.out.println(j+":"+(n-j)); break; } }//for arr } // System.out.println(Arrays.toString(arr)); for(int i : arr){ System.out.print(i+" "); } } }
37、货车运货,输入货车载重,A物品重量,A物品价值,B物品重量,B物品价值,A和B必须都有至少一件,货车需要刚好装满发车,问最大发车价值是多少
public class KnapsackProblem { public static void main(String[] args) { // 货车的载重 int truckWeight = 10; // 定义物品A的重量和价值 int weightA = 5; int valueA = 20; // 定义物品B的重量和价值 int weightB = 6; int valueB = 30; // 计算物品A和B的单位价值 double valuePerWeightA = (double) valueA / weightA; double valuePerWeightB = (double) valueB / weightB; // 计算总价值 int maxValue = 0; if (truckWeight >= weightA + weightB) { maxValue = valueA + valueB; } else if (truckWeight >= weightA && weightA > 0) { maxValue = (int) (valuePerWeightA * truckWeight); } else if (truckWeight >= weightB && weightB > 0) { maxValue = (int) (valuePerWeightB * truckWeight); } System.out.println("最大价值为: " + maxValue); } }
假设货车的载重是固定的,并且物品A和物品B的重量和价值也是已知的。程序首先计算每种物品的单位价值,然后根据货车的载重来决定是选择物品A、物品B或者两者都不选,最后输出在给定条件下的最大价值
38、给出10的字符串 ,1表示一个位子有人坐着 0表示没有,因为疫情两个人不能紧挨着坐,问给出的01串中间还能在安排几个人坐位子(之前坐着的人不能移动位置)
public class DeskOccupancy { public static void main(String[] args) { String[] desks = {"10010", "01001", "00100", "10101", "00000", "10101", "01001", "10001", "00101", "10100"}; int occupiedDesks = 0; for (String desk : desks) { if (desk.charAt(0) == '1') { occupiedDesks++; } for (int i = 1; i < desk.length(); i++) { if (desk.charAt(i) == '1' && desk.charAt(i - 1) == '1') { occupiedDesks--; break; } else if (desk.charAt(i) == '1') { occupiedDesks++; } } } System.out.println("总人数:" + occupiedDesks); } }
这段代码会统计并输出总人数。它会遍历桌子的字符串数组,对于每个字符串,它首先检查第一个位置是否有人,并相应地增加或减少人数。然后,它遍历剩余的位置,如果发现有两个连续的“1”,则人数减少,表示排除了紧挨着的情况。最终输出总人数
39、从一段文本中去掉符号提取单词,问里面有多少单词的前缀是某个固定的pre(长度小于20的字符串)
public class PrefixExtractor { public static void main(String[] args) { String text = "Hello, this is a test string with symbols. How are you?"; String pre = "test"; int length = 5; // 假设我们只关心前缀长度为5的单词 // 将文本转换为小写并用空格分隔 String lowerCaseText = text.toLowerCase().replaceAll("[^a-zA-Z ]", ""); // 根据空格分割文本以获取单词列表 String[] words = lowerCaseText.split("\\s+"); // 遍历单词列表,检查前缀 int count = 0; for (String word : words) { if (word.length() >= length && word.startsWith(pre)) { count++; // 打印满足条件的单词(如果需要) System.out.println(word); } } // 输出前缀单词的数量 System.out.println("Number of words with prefix '" + pre + "' of length " + length + ": " + count); } }
这段代码首先将输入文本转换为小写并去除非字母非空格字符,然后根据空格分割成单词数组。接着遍历单词数组,检查每个单词是否以给定的前缀pre开始,并且长度大于或等于指定的length。最后,它打印出所有满足条件的单词并输出以该前缀开始的单词数量
40、输入描述第一行为一个数N,表示有N个数,1<=N<=10000第二行为N个空格分隔的整数,每个数的范围为[1,10000]输出描述输出树的高度(根节点的高度为1)
import java.util.Scanner; public class ReadNumbers { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Enter the number of integers: "); int N = scanner.nextInt(); int[] numbers = new int[N]; System.out.println("Enter " + N + " space-separated integers:"); for (int i = 0; i < N; i++) { numbers[i] = scanner.nextInt(); } scanner.close(); // 输出数组中的整数,以验证读取是否正确 System.out.println("The numbers you entered are:"); for (int number : numbers) { System.out.print(number + " "); } } }
这个程序使用了Java的Scanner类来读取输入。它首先要求用户输入一个整数N,然后读取N个整数,并将它们存储在一个数组中。程序的最后部分输出了用户输入的整数,以验证读取是否成功
41、提取字符串中的最长合法简单数学表达式n计算表达式的值。如果没有,则返回0n简单数学表达式只能包含以下内容n0-9数字,符号±*/n说明:
n1.所有数字,计算结果都不超过long
n2.如果有多个长度一样的,请返回第一个表达式的结果
n3.数学表达式,必须是最长的,合法的
n4.操作符不能连续出现,如 ±-+1 是不合法的
import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { String input = "123+456-789*123+456-789*123+456-789*123+456-789"; System.out.println(calculateLongestMathExpression(input)); } public static int calculateLongestMathExpression(String input) { // 正则表达式匹配数学表达式 String regex = "(\\d+(\\*\\d+)*(\\+|-\\d+)*)+"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); // 用于存储最长的表达式 String longestExpression = ""; int longestValue = 0; // 遍历所有匹配项,找到最长的表达式 while (matcher.find()) { String expression = matcher.group(); if (expression.length() > longestExpression.length()) { longestExpression = expression; } } // 如果存在最长表达式,计算它的值 if (!longestExpression.isEmpty()) { longestValue = calculateExpression(longestExpression); } return longestValue; } // 计算给定的数学表达式的值 public static int calculateExpression(String expression) { // 这里简单处理,不考虑括号和高精度计算 String[] tokens = expression.split("\\+|-\\*"); int value = 0; for (String token : tokens) { if (!token.isEmpty()) { int number = Integer.parseInt(token); if (expression.charAt(0) == '-') { value -= number; } else { value += number; } } } return value; } }
这个代码会找到输入字符串中最长的合法数学表达式,并计算它的值。如果没有找到合法的表达式,则返回0。这个解决方案假设输入的表达式只包含加(+)、减(-)和乘(*)操作,并且没有括号。对于更复杂的情况,可能需要进一步扩展正则表达式和计算表达式的方法。
42、输入描述n会议室座位总数seatNum。(1 <= seatNum <= 500)员工的进出顺序 seatOrLeave 数组,元素值为 1,表示进场;元素值为负数,表示出场(特殊:位置 0 的员工不会离开)。例如 -4 表示坐在位置 4 的员工离开(保证有员工坐在该座位上)输出描述n最后进来员工,他会坐在第几个位置,如果位置已满,则输出-1。用例输入10 [1,1,1,1,-4,1]输出5
解决方案1:使用数组来模拟会议室座位
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int seatNum = sc.nextInt(); // 输入座位总数 boolean[] seats = new boolean[seatNum]; // 使用布尔数组模拟座位 // 初始化所有座位为空闲状态 for (int i = 0; i < seats.length; i++) { seats[i] = true; } // 输入员工的进出顺序 while (sc.hasNext()) { String action = sc.next(); int employeeId = sc.nextInt(); if (action.equals("ENTER")) { int seatNumber = sc.nextInt(); // 输入员工需要坐的座位号 if (seats[seatNumber - 1]) { // 如果该座位空闲 System.out.println(employeeId + " is seated in seat number " + seatNumber); seats[seatNumber - 1] = false; // 标记为已坐 } else { System.out.println(employeeId + " cannot be seated"); } } else if (action.equals("EXIT")) { // 输入员工离座的座位号 int seatNumber = sc.nextInt(); if (!seats[seatNumber - 1]) { // 如果该座位不空闲 System.out.println(employeeId + " stands up from seat number " + seatNumber); seats[seatNumber - 1] = true; // 标记为空闲 } else { System.out.println(employeeId + " cannot stand up"); } } } sc.close(); } }
解决方案2:使用链表来模拟会议室座位
import java.util.LinkedList; import java.util.Scanner; import java.util.NoSuchElementException; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int seatNum = sc.nextInt(); // 输入座位总数 LinkedList<Integer> seats = new LinkedList<>(); // 初始化所有座位 for (int i = 1; i <= seatNum; i++) { seats.add(i); } // 输入员工的进出顺序 while (sc.hasNext()) { String action = sc.next(); int employeeId = sc.nextInt(); if (action.equals("ENTER")) { int seatNumber = sc.nextInt(); // 输入员工需要坐的座位号 try { seats.remove(seatNumber - 1); // 尝试坐下 System.out.println(employeeId + " is seated in seat number " + seatNumber); } catch (IndexOutOfBoundsException e) { System.out.println(employeeId + " cannot be seated"); } } else if (action.equals("EXIT")) { int seatNumber = sc.nextInt(); // 输入员工离座的座位号 try { seats.add(seatNumber - 1, employeeId); // 尝试站起 System.out.println(employeeId + " stands up from seat number " + seatNumber); } catch (IndexOutOfBoundsException e) { System.out.println(employeeId + " cannot stand up"); } } } sc.close(); } }``` 43、最后一题是执mkdir cd pwd序列 在Java中,执行mkdir、cd和pwd序列的操作可以通过java.io.File类来实现。以下是一个简单的示例代码,展示了如何在Java中创建目录、改变当前工作目录以及打印当前工作目录的路径 ```java import java.io.File; public class DirectoryOperations { public static void main(String[] args) { // 创建一个File对象表示新目录 File newDirectory = new File("newDirectory"); // 使用mkdir()方法创建新目录 boolean directoryCreated = newDirectory.mkdir(); if (directoryCreated) { System.out.println("Directory created successfully."); // 改变当前工作目录到新创建的目录 boolean directoryChanged = newDirectory.setCurrent(); if (directoryChanged) { System.out.println("Changed working directory to: " + newDirectory.getAbsolutePath()); // 打印当前工作目录 System.out.println("Working directory: " + System.getProperty("user.dir")); } else { System.out.println("Could not change working directory."); } } else { System.out.println("Directory already exists or could not be created."); } } }
// 打印当前工作目录
System.out.println("Working directory: " + System.getProperty(“user.dir”));
44、火星文计算,火星文:x#y可以翻译为地球文4*x+3+y ,火星文xKaTeX parse error: Expected 'EOF', got '#' at position 17: …可以翻译为2*x+y+3 其中#̲的运算优先级高于 要求计算火星文的表达式结果 如5#6$7#8
例如:123#4$5#67$78。
输入
7#6$5#12
输出
226
说明
示例
7#6$5#12
=7#(36+5+2)#12
=7#25#12
=(27+325+4)#12
=93#12
=293+3*12+4
=226
package OD真题.火星文计算; import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; public class Main { // eg: 7#6$5#12 public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String s = scanner.nextLine(); scanner.close(); // 将字符串转化为字符数组(转化后的数字都是单个的,比如 12 会转化为 1, 2) // [7, #, 6, $, 5, #, 1, 2] char[] chars = s.toCharArray(); // 用于数字合并(将 1, 2 转化为 12) String num = ""; // 用于接收 便于使用的 表达试的List(数字是一位, 字符是一位) ArrayList<String> numList = new ArrayList<>(); // 遍历字符数组 for (char c : chars) { // 如果此字符是数字就加到合并数组的字符串 if (Character.isDigit(c)) { num = num + c; } else { // 如果遇到 操作符 将数字加入 List numList.add(num); // 将操作符也加入list numList.add(String.valueOf(c)); // 置空字符串,用于下次组合数字 num = ""; } } // 最后一位数字 后面是没有 字符的, 故需要把最后一个数字加入 List numList.add(num); // 遍历组合好的 表达式List(先处理优先的操作) // 转化好的 : numList : [7, #, 6, $, 5, #, 12] for (int i = 0; i < numList.size(); i++) { // 遇到需要转化的操作符 if (numList.get(i).equals("$")) { // 转化为对应的数学表达式 int temp = 3 * Integer.parseInt(numList.get(i-1)) + Integer.parseInt(numList.get(i+1)) + 2; // 将结果 加到转化的表达式的前面 numList.add(i-1, Integer.toString(temp)); // 移除原来的表达式 numList.remove(i); numList.remove(i); numList.remove(i); // 移除后坐标会发生变化,故需要从头遍历 i = 0; } } // [7, #, 25, #, 12] for (int i = 0; i < numList.size(); i++) { if (numList.get(i).equals("#")) { int temp = 2 * Integer.parseInt(numList.get(i-1)) + 3 * Integer.parseInt(numList.get(i+1)) + 4; // [93, 7, #, 25, #, 12] numList.add(i-1, Integer.toString(temp)); // [93, #, 25, #, 12] numList.remove(i); // [93, 25, #, 12] numList.remove(i); // [93, #, 12] numList.remove(i); // 此时 i = 1, 再次循环时,i = 2,就无法再遍历到字符 进行转化操作了 // 故需要 将 i 变成 0 ,从头遍历 i = 0; } } System.out.println(Arrays.toString(numList.toArray())); } }
45*、幼儿园老师要小朋友回忆班里有几个同小区的同学 形成一个数组[2,2,3],题目问题是小朋友至少来自几个小区,示例是输入[2,2,3]意思是第一个小朋友有两个同学在同一个小区,第二个小朋友也有两个同学在同一个小区,第三个小朋友有三个同学在一个小区最后输出是7
???
46、小朋友分班:题目描述
幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友同班,请你帮忙把同班的小朋友找出来小朋友的编号是整数,与前一位小朋友同班用Y表示,不同班用N表示学生序号范围(0,999],如果输入不合法则打印ERROR。
输入描述
输入为空格分开的小朋友编号和是否同班标志
输出描述
输出为两行,每一行记录一个班小朋友的编号,编号用空格分开,且:
1.编号需按照升序排列,分班记录中第一个编号小的排在第一行。
2.若只有一个班的小朋友,第二行为空行。
输入 1/N 2/Y 3/N 4/Y
输出 1 2 3 4
说明 2的同班标记为Y,因此和1同班。
3的同班标记为N,因此和1、2不同班。
4的同班标记为Y,因此和3同班。
所以1、2同班,3、4同班,输出为1 2 3 4
public class TestClass { public static void main(String[] args) { //1/N 2/Y 3/N 4/Y //6/N 2/Y 3/N 4/Y 5/Y 7/N 8/Y Scanner scanner = new Scanner(System.in); System.out.print("输入小朋友的编号:"); String str = scanner.nextLine(); // System.out.println(str); String[] childrens = str.split(" "); // System.out.println(Arrays.toString(childrens)); //创建双端队列对象 ArrayDeque<String> arr_one = new ArrayDeque<>(); ArrayDeque<String> arr_two = new ArrayDeque<>(); //调用方法 getBranch(childrens, arr_one, arr_two); show(arr_one); show(arr_two); } /** * 显示数据 * * @param arr */ private static void show(ArrayDeque<String> arr) { //使用Lambda,分割之后,再进行排序。 System.out.println(arr.stream().map(s -> s.split("/")[0]).sorted().collect(Collectors.joining(" ")).trim()); } /** * 分班 * @param childrens * @param arr1 * @param arr2 */ private static void getBranch(String[] childrens, ArrayDeque<String> arr1, ArrayDeque<String> arr2) { ArrayDeque<String> temp = null; //循环 for (String chs : childrens) { //判断当前对象是否为空 if (Objects.isNull(temp)) { temp = arr1; //给当前队列赋值 } else if (chs.endsWith("N")) { //判断尾端是否为N temp = temp.equals(arr1) ? (arr2) : (arr1); } //添加到最后 temp.offerLast(chs); } } }``` 47、给定正整数n,如果n可以分解成m(m>1)个连续正整数之和,输出m最小的分解情况;如果n不能分成连续正整数之和,输出"N" 例:输入21输出21=10+11 ```java public static void main(String[] args) { String result="NO"; Scanner sc = new Scanner(System.in); int sum = sc.nextInt(); // (N - k(k-1)/2) / k for ( int k=2; k < sum; k++) { int x=(sum - k*(k-1)/2) / k; //开始值 int m= (sum - k*(k-1)/2) % k; if (x<0){ result="NO"; break; } if (m!=0){ k++; }else { result="YES"; break; } } System.out.println(result); }
49、三叉树的每个结点都储存一个数字;输入一串数字,构造三叉搜索树,并输出其高度
如果数字小于当前根结点减500,将其插入到左子树上;
如果数字大于当前根结点加500,将其插入到右子树上;
否则插入到中子树上
输入第一行是要插入的结点总数,第二行是结点
输出构造好的三叉树的高度
例输入55000 2000 5000 8000 1800输出3
解释:
构造为
5000
/ |
/ |
2000 5000 8000
/
/
1800
共3层
class Node { int value; Node left; Node middle; Node right; Node(int value) { this.value = value; this.left = null; this.middle = null; this.right = null; } } public class ThreeWayTree { public static Node insert(Node node, int value) { if (node == null) { return new Node(value); } if (value < node.value) { node.left = insert(node.left, value); } else if (value > node.value) { node.right = insert(node.right, value); } else { node.middle = insert(node.middle, value); } return node; } public static int height(Node node) { if (node == null) { return 0; } int leftHeight = height(node.left); int middleHeight = height(node.middle); int rightHeight = height(node.right); return 1 + Math.max(leftHeight, Math.max(middleHeight, rightHeight)); } public static void main(String[] args) { Node root = null; int[] numbers = {50, 25, 75, 15, 35, 60, 80}; for (int number : numbers) { root = insert(root, number); } System.out.println("Height of the tree: " + height(root)); } }
这段代码定义了一个Node类来表示三叉搜索树的节点,其中储存了一个数字和三个子节点。insert方法用于将数字插入到三叉搜索树中。height方法用于计算树的高度。在main方法中,我们创建了一个空的根节点,并通过循环将数组中的数字插入到树中,然后计算并打印树的高度。
50、构造哈夫曼树并输出中序遍历的结果,要求左子树权重小于右子树权重,权重相等时左子树高度小于右子树高度
import java.util.ArrayList; import java.util.List; import java.util.PriorityQueue; public class HuffmanTree { // 定义节点类 static class Node implements Comparable<Node> { int weight; Node left; Node right; Node(int weight) { this.weight = weight; } @Override public int compareTo(Node other) { return this.weight - other.weight; } } // 构建哈夫曼树 static Node buildTree(int[] weights) { PriorityQueue<Node> priorityQueue = new PriorityQueue<>(); for (int weight : weights) { priorityQueue.add(new Node(weight)); } while (priorityQueue.size() > 1) { Node left = priorityQueue.poll(); Node right = priorityQueue.poll(); Node parent = new Node(left.weight + right.weight); parent.left = left; parent.right = right; priorityQueue.add(parent); } return priorityQueue.poll(); } // 中序遍历哈夫曼树 static void inorderTraversal(Node node) { if (node == null) { return; } inorderTraversal(node.left); System.out.print(node.weight + " "); inorderTraversal(node.right); } public static void main(String[] args) { int[] weights = {7, 5, 2, 4}; // 示例权重数组 Node huffmanTree = buildTree(weights); inorderTraversal(huffmanTree); // 输出中序遍历结果 } }
这段代码首先定义了一个Node类来表示哈夫曼树的节点,并实现了Comparable接口以便于节点的排序。buildTree方法使用优先队列来构建哈夫曼树,inorderTraversal方法则是对构建好的哈夫曼树进行中序遍历,并打印每个节点的权重。在main方法中,我们创建了一个权重数组,并调用buildTree方法来构建哈夫曼树,然后调用inorderTraversal方法输出中序遍历的结果
51、(贪心)有一个0,1字符串,0表示不停车,1表示停车位。有3种车型,分别占用1、2、3个停车位,输入给定字符串,输出停满需要的最少车子数量
思路:
minCarCount是我们最后要输出的数
placseCount是停车场有车位的数
遍历车位:
如果1:placseCount++
如果非1但是placseCount非0: minCarCount++ placseCount=0
如果placseCount===3或是最后一个车位: minCarCount++ placseCount=0
function carParks(cars) { let placseCount = 0; let minCarCount = 0; for (let i = 0; i < cars.length; i++) { if (cars[i] === 1) { placseCount++; } else if (placseCount != 0) { minCarCount++; placseCount = 0; } if (placseCount === 3 || i == cars.length - 1) { minCarCount++; placseCount = 0 } } console.log(minCarCount); } carParks([1,0,1,1,1,1])
52、(排序后贪心)二元组[x,y]表示会议时间段,如果2个会议时间段有重合部分则可以合并,(例如[1,3]+[3,4]=[1,4]; [1,4]+[2,3]=[1,4])输入若干会议的会议时间段,输出完全合并后的时间段
import java.util.Arrays; public class MeetingRooms { public static boolean canAttendMeetings(int[][] intervals) { if (intervals.length <= 1) { return true; } // 按会议开始时间对会议时间段进行排序 Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])); int currentMeetingEnd = intervals[0][1]; for (int i = 1; i < intervals.length; i++) { if (currentMeetingEnd > intervals[i][0]) { // 发生重叠 return false; } else { // 更新最晚结束时间 currentMeetingEnd = intervals[i][1]; } } return true; } public static void main(String[] args) { int[][] intervals = {{0, 30},{5, 10},{15, 20}}; boolean canAttend = canAttendMeetings(intervals); System.out.println("Can attend all meetings? " + canAttend); } }
这段代码首先对会议时间段按照开始时间进行排序,然后通过一个贪心策略来判断所有会议是否可以都参加。如果当前会议的结束时间晚于下一个会议的开始时间,则发生重叠,返回false;否则更新最晚结束时间并继续下一轮比较。如果所有会议都不重叠,则返回true。
53、找座位,0代表没人,1代表有人,两人之间至少隔一个空座,要求算出最多能再坐几个人。输入例10001,输出例1
解法1:
public class Solution {
public int maxDistToClosest(int[] seats) {
int maxDist = 0;
int counter = 0;
for (int i = 0; i < seats.length; i++) {
if (seats[i] == 0) {
counter++;
} else {
maxDist = Math.max(maxDist, counter);
counter = 0;
}
}
return Math.max(maxDist, counter);
}
}
解法2:
public class Solution {
public int maxDistToClosest(int[] seats) {
int maxDist = 0;
int counter = 0;
for (int i = 0; i < seats.length; i++) {
if (seats[i] == 1) {
maxDist = Math.max(maxDist, counter);
counter = 0;
} else {
counter++;
}
}
return Math.max(maxDist, counter);
}
}
解法3:
public class Solution {
public int maxDistToClosest(int[] seats) {
int maxDist = 0;
int counter = 0;
for (int i = 0; i < seats.length; i++) {
if (seats[i] == 1) {
counter = 0;
} else {
counter++;
maxDist = Math.max(maxDist, counter);
}
}
return maxDist;
}
}
以上三种解法都是基于同样的思路,遍历数组,遇到0则计数器加一,遇到1则计数器清零,并更新最大距离。最后返回最大距离即可。
注意:这里的座位是指数组中的位置,0表示没有人坐在这个位置,1表示有人坐在这个位置。两个人之间的最大距离指的是在不违反规则(至少隔一个空座)的情况下,最多可以坐多少个人
55、100个内存,求能申请到的最合适的内存块的下标,第一行输入要申请内存的大小,后面2到n行,第一个数表示已使用内存的下标起始位置,第二个数表示这片连续内存的长度
//假设你有一个100个元素的数组,表示内存块,每个内存块可用的字节数如下 int[] memoryBlocks = new int[100]; // 假设已经初始化并填充了内存块大小 //你需要一个方法来找到最适合申请的内存块的下标。以下是一个简单的方法,用于找到第一个可以满足申请大小的内存块的下标: public int findBestFitIndex(int[] memoryBlocks, int requestSize) { for (int i = 0; i < memoryBlocks.length; i++) { if (memoryBlocks[i] >= requestSize) { return i; } } return -1; // 如果没有足够大的内存块可以满足需求,则返回-1 } int requestSize = 25; // 假设有一个申请,需要25个内存 int index = findBestFitIndex(memoryBlocks, requestSize); if (index != -1) { System.out.println("最适合的内存块下标是: " + index); } else { System.out.println("没有足够大的可用内存块。"); } //这个方法会遍历内存块数组,寻找第一个可以满足申请大小的内存块。如果没有找到,则返回-1。这是一个简单的适合入门的算法,实际操作系统中的内存分配策略可能更为复杂。
56、猴子摘香蕉;
一个房间里,天花板上挂有一串香蕉,有一只猴子可在房间里任意活动(到处走动,推移箱子,攀登箱子等)。设房间里还有一只可被猴子移动的箱子,且猴子登上箱子时才能摘到香蕉,问猴子在某一状态下(设猴子位置为A,香蕉位置在B,箱子位置为C),如何行动可摘取到香蕉。
用java实现猴子摘香蕉
在题目中要求以一维方式实现,但实际上我们可以将三个物体的位置拓展到二维,既将它们的位置设为(x,y)
monkey类:
public class monkey { public int x, y; monkey(){ } monkey(int x, int y){ this.x = x; this.y = y; } public void monkeymove(int x, int y){ if (this.x == x && this.y == y) return; System.out.println("猴子从("+this.x+","+this.y+")移动到了("+x+","+y+")"); this.x = x; this.y = y; } public void movebox(box b, int x, int y){ if (b.x == x && b.y == y) return; System.out.println("猴子将箱子从("+this.x+","+this.y+")移动到了("+x+","+y+")"); this.x = x; this.y = y; b.setX(x); b.setY(y); return; } public void climb(){ System.out.println("猴子爬上了箱子"); } }
banana类:
public class banana {
public int x, y;
banana(){
}
banana(int x, int y){
this.x = x;
this.y = y;
}
}
box类:
public class box { public int x, y; box(){ } box(int x, int y){ this.x = x; this.y = y; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } }
main函数如下:
import java.util.Scanner; public class monkeyreachbanana { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("房间大小为16x16"); int x, y; System.out.println("请输入猴子的位置(x,y)"); x = sc.nextInt(); y = sc.nextInt(); while (x > 16 || x < 0 ||y > 16 || y < 0) { System.out.println("输入位置有误,请重新输入"); x = sc.nextInt(); y = sc.nextInt(); } monkey hou = new monkey(x, y); System.out.println("请输入箱子的位置(x,y)"); x = sc.nextInt(); y = sc.nextInt(); while (x > 16 || x < 0 ||y > 16 || y < 0) { System.out.println("输入位置有误,请重新输入"); x = sc.nextInt(); y = sc.nextInt(); } box xiang = new box(x, y); System.out.println("请输入香蕉的位置(x,y)"); x = sc.nextInt(); y = sc.nextInt(); while (x > 16 || x < 0 ||y > 16 || y < 0) { System.out.println("输入位置有误,请重新输入"); x = sc.nextInt(); y = sc.nextInt(); } banana jiao = new banana(x, y); start(hou, xiang, jiao); return; } private static void start(monkey hou, box xiang, banana jiao) { while (!reach(hou, xiang, jiao)) { hou.monkeymove(xiang.x, xiang.y); hou.movebox(xiang, jiao.x ,jiao.y); } hou.climb(); System.out.println("猴子摘到了香蕉"); } public static boolean reach(monkey hou, box xiang, banana jiao){ if (hou.x == xiang.x && xiang.x == jiao.x && hou.y == xiang.y && xiang.y == jiao.y) return true; else return false; } }
57、石头剪刀布游戏
分别用字母A、B、C表示石头剪刀布,会有若干行数据
作为用户id和字母
例如:
user1 A
user2 B
此时A胜出,输出user1
user1 A
user2 A
此时双方平局,输出NULL
package javaLab2; import java.util.Scanner; public class Paper012 { // public static int ran,num; public static void compute() { int ran,num; ran = (int)(Math.random()*3); System.out.println("please enter a number:"); Scanner input = new Scanner(System.in); num = input.nextInt(); if(num > 2 || num < 0) { System.out.println("input error,please enter again"); compute(); } //游戏过程计算 int a = 0;//用来记录次序 if(ran == 0 && num == 0) a = 1; if(ran == 0 && num == 1) a = 2; if(ran == 0 && num == 2) a = 3; if(ran == 1 && num == 0) a = 4; if(ran == 1 && num == 1) a = 5; if(ran == 1 && num == 2) a = 6; if(ran == 2 && num == 0) a = 7; if(ran == 2 && num == 1) a = 8; if(ran == 2 && num == 2) a = 9; switch(a) { case 1: System.out.println("The computer selects scissors. You select scissors too. It is a draw."); break; case 2: System.out.println("The computer selects scissors. You select rock.You win!"); break; case 3: System.out.println("The computer selects scissors. You select paper.You are lost!"); break; case 4: System.out.println("The computer selects rock. You select scissors.You are lost!"); break; case 5: System.out.println("The computer selects rock. You select rock too. It is a draw."); break; case 6: System.out.println("The computer selects rock. You select paper.You win!"); break; case 7: System.out.println("The computer selects paper. You select scissors.You win!"); break; case 8: System.out.println("The computer selects paper. You select rock.You are lost!"); break; case 9: System.out.println("The computer selects paper. You select paper too. It is a draw."); break; } } public static void main(String[] args) { System.out.println("scissors (0), rock (1), paper (2)"); Scanner input = new Scanner(System.in); System.out.println("Computer will generate a random number\nThe Game Begins"); int ran; int num; compute(); int b ;//判断是否要继续玩的变量 do { System.out.println("Do you still want to play? yes(1),no(0) "); b = input.nextInt(); if(b == 1) { compute(); } }while(b != 0); } }
58、url请求热点计算数量
输入:
2
/aaa/bbb
/aaa/bbb/cc
2 bbb
输出:
2
解释:
第1行表示接下来输入两行URL
第4行表示,在分段为2的路径中计算bbb出现的次数,输出结果为2,表示bbb出现了2次;
要使用Java进行URL请求并计算热点的数量,你可以使用java.net.HttpURLConnection类或者java.net.URL类配合第三方库如Apache HttpClient进行网络请求。然后解析响应内容以计算热点数量。
以下是一个简单的例子,使用java.net.HttpURLConnection类从URL获取内容,并假设热点数量由HTML中某个特定字符串标识(例如"hotspot")。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class HotspotCounter { public static void main(String[] args) throws Exception { String urlString = "http://www.example.com"; // 替换为你的URL URL url = new URL(urlString); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer content = new StringBuffer(); while ((inputLine = in.readLine()) != null) { content.append(inputLine); } in.close(); String hotspotString = "hotspot"; // 替换为你的热点标识 long count = content.toString().split(hotspotString).length - 1; System.out.println("Number of hotspots: " + count); } else { System.out.println("GET request not worked"); } } }
请根据你的实际热点标识(可能是一个HTML标签、特定的class或id等)进行相应的字符串替换。这个简单的例子只是给你一个起点,实际应用中可能需要更复杂的解析逻辑来准确计算热点数量。
59、一个二叉树,求二叉树的从根节点到子节点的最大路径和
具体的思路:
递归函数设计: 设计一个递归函数,该函数的任务是计算包含当前节点的最大路径和。函数的返回值应该是从当前节点出发到任意叶子节点的最大路径和。
递归终止条件: 在递归函数中,需要处理递归的终止条件。当当前节点为 null 时,返回 0,表示空路径的和为 0。
递归计算左右子树的最大路径和: 对于当前节点,递归计算左右子树的最大路径和。如果子树的最大路径和为负数,可以选择不包含该子树,将其贡献值设为 0。
更新全局最大路径和: 在递归的过程中,不断更新全局最大路径和。全局最大路径和是包含当前节点值的最大路径和,可能由左子树、右子树和当前节点共同组成。
返回当前子树的最大路径和: 在递归函数的最后,返回当前子树的最大路径和。
class TreeNode { int val; TreeNode left; TreeNode right; public TreeNode(int val) { this.val = val; } } public class MaxPathSum { int maxSum = Integer.MIN_VALUE; public int maxPathSum(TreeNode root) { if (root == null) { return 0; } // 递归计算左右子树的最大路径和 int leftMax = Math.max(maxPathSum(root.left), 0); int rightMax = Math.max(maxPathSum(root.right), 0); // 更新全局最大路径和 maxSum = Math.max(maxSum, root.val + leftMax + rightMax); // 返回当前子树的最大路径和(只能选择左子树或右子树) return root.val + Math.max(leftMax, rightMax); } public static void main(String[] args) { MaxPathSum solution = new MaxPathSum(); // 构造一棵二叉树(示例) TreeNode root = new TreeNode(10); root.left = new TreeNode(2); root.right = new TreeNode(10); root.left.left = new TreeNode(20); root.left.right = new TreeNode(-15); root.right.right = new TreeNode(20); root.left.left.left = new TreeNode(-20); root.right.right.left = new TreeNode(3); root.right.right.right = new TreeNode(-4); int result = solution.maxPathSum(root); System.out.println("最大路径和: " + result); } }
这个实现中,maxPathSum 方法返回的是以当前节点为根的最大路径和。在递归的过程中,不断更新 maxSum 变量,最终得到整棵树的最大路径和。
60、机器人搬砖问题,二分法,跟猴子吃桃类似,一个小时只能搬一个仓库,求8个小时搬完所有个仓库的砖的最小速度
理解为机器人搬砖,一共有N堆砖存放在N个不同的仓库中,第i堆砖中有bricks[i]块砖头,要求在8小时内搬完。机器人每小时能搬砖的数量取决于有多少能量格,机器人一个小时中只能在一个仓库中搬砖,机器人的能量格每小时补充一次且能量格只在这一个小时有效,为使得机器人损耗最小化尽量减小每次补充的能量格数 为了保障在8小时内能完成搬砖任务,请计算每小时给机器人充能的最小能量格数
import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int[] bricks = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray(); System.out.println(getResult(bricks)); } public static int getResult(int[] bricks) { // 机器人每小时只能在一个仓库干活,因此给定8小时,最多只能搬完8个仓库,如果仓库数量超过8,那么肯定干不完 if (bricks.length > 8) { return -1; } // 每小时最多需要的能量块 int max = Arrays.stream(bricks).max().orElse(0); // 如果有8个仓库,那么只能1个小时干1个仓库,且机器人每小时需要能量至少是max(bricks),这样才能保证1个小时内把最多砖块的那个仓库搬完 if (bricks.length == 8) { return max; } // 如果仓库数少于8个,那么此时每小时能量max(bricks)必然能在8小时内搬完所有仓库,但不是最优解 int ans = max; // 每小时最少需要的能量块 int min = 1; // 二分法 while (min <= max) { // 取中间值 int mid = (min + max) >> 1; if (check(mid, 8, bricks)) { // 如果每小时充mid格能量,就能在8小时内,搬完所有砖头,则mid就是一个可能解 ans = mid; // 但mid不一定是最优解,因此继续尝试更小的能量块 max = mid - 1; } else { // 如果每小时充mid能量块,无法在8小时能完成工作,则说明每天能量块充少了,下次应该尝试充更多能量块 min = mid + 1; } } return ans; } /** * @param energy 每小时可以使用的能量块数量 * @param limit 限制几小时内干完 * @param bricks 要搬几堆砖头 * @return 是否可以在limit小时内已指定energy能量办完所有bricks */ public static boolean check(int energy, int limit, int[] bricks) { // 已花费的小时数 int cost = 0; for (int brick : bricks) { cost += brick / energy + (brick % energy > 0 ? 1 : 0); // 如果搬砖过程中发现,花费时间已经超过限制,则直接返回false if (cost > limit) { return false; } } return true; } }
61、合并会议室占用区间,二位列表,每个列表代表会议室被占用的开会时间,合并时间之和再输出
62、机器人从(0,0)出发,E为最终横坐标位置,n表示输入移动次数,x是移动至的横坐标,offsetY是纵坐标移动数量,offsetY负数表示向下移动,求图形面积
输入示例
2 4
0 1
2 -2
输出结果
4
输入描述:
第1行输入为M和N,M表示网格的行数N表示网格的列数之后M行表示网格数值,每行N个数值(数值大小用k表示),数值间用单个空格分隔,行首行尾无多余空格M、N、k均为整数,且1≤M,N≤150,0≤k≤50
输出描述:
输出1行,包含1个数字,表示最大活动区域的网格点数目行首行尾无多余空格
import java.io.*; import java.util.LinkedList; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] strings = br.readLine().split(" "); int row = Integer.parseInt(strings[0]), col = Integer.parseInt(strings[1]), max = 0; int[][] nums = new int[row][col]; for (int i = 0; i < row; i++) { String[] split = br.readLine().split(" "); for (int j = 0; j < col; j++) { nums[i][j] = Integer.parseInt(split[j]); } } boolean[][] status = new boolean[row][col]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (!status[i][j]) { LinkedList<int[]> q = new LinkedList<>(); q.offer(new int[]{i, j, nums[i][j]}); int sum = 1; status[i][j] = true; while (!q.isEmpty()) { int[] temp = q.poll(); int x = temp[0], y = temp[1], pre = temp[2]; sum = getSum(row, col, nums, status, q, sum, x - 1, y, pre); sum = getSum(row, col, nums, status, q, sum, x + 1, y, pre); sum = getSum(row, col, nums, status, q, sum, x, y - 1, pre); sum = getSum(row, col, nums, status, q, sum, x, y + 1, pre); } max = Math.max(max, sum); } } } System.out.println(max); } private static int getSum(int row, int col, int[][] nums, boolean[][] status, LinkedList<int[]> q, int sum, int x, int y, int pre) { if (x >= 0 && x < row && y >= 0 && y < col && !status[x][y] && Math.abs(nums[x][y] - pre) <= 1) { q.offer(new int[]{x, y, nums[x][y]}); sum++; status[x][y] = true; } return sum; } }
63、身高体重排序:n为学生编号,从1开始,身高从低到高排序,同样身高体重低的排前面,身高体重相同保持原来的排序不变,输出学生的编号
输入
首行是学生人数
第二行为学生身高
第三行为学生体重
输出
学生编号
思路:可以直接将身高体重存入二维数组,序列为首列,第二列为身高,第三列为体重
import java.util.Arrays; import java.util.Comparator; public class Student { int n; int height; int weight; public Student(int n, int height, int weight) { this.n = n; this.height = height; this.weight = weight; } public static void main(String[] args) { Student[] students = { new Student(1, 160, 50), new Student(2, 170, 40), new Student(3, 160, 55), new Student(4, 170, 55), new Student(5, 180, 45) }; Arrays.sort(students, new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { if (s1.height != s2.height) { return Integer.compare(s1.height, s2.height); } else { return Integer.compare(s1.weight, s2.weight); } } }); for (Student s : students) { System.out.println("学生编号: " + s.n + ", 身高: " + s.height + ", 体重: " + s.weight); } } }
这段代码定义了一个Student类,并在main方法中创建了一个Student数组。使用Arrays.sort方法和Comparator接口重载了排序规则,先按身高升序排列,身高相同时按体重升序排列。最后打印排序后的学生信息。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。