1. 移除元素
需求:
给你一个数组 nums 和一个值 val,你需要删除所有数值等于 val 的元素
举例1:
输入:nums = [3,2,2,3] val = 3
输出:nums = [2,2] 剩余2个元素
举例1:
输入:nums = [0,1,2,2,3,0,4,2] val = 2
输出:nums = [0,1,4,0,3] 剩余5个元素
思路
利用快慢针实现
代码
java
package unit7;
import java.util.Scanner;
public class text1 {
//移除元素
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int val = sc.nextInt();
int num = 0;
int[] nums = new int[n];
for(int i = 0; i< n; i++){
nums[i] = sc.nextInt();
if(nums[i] != val){
num++;
}
}
int[] ret = new int[num];
int slow = 0;
int fast = 0;
while(fast < n){
if(nums[fast] == val){
fast++;
}else{
ret[slow++] = nums[fast++];
}
}
for(int i = 0; i < ret.length; i++){
System.out.print(ret[i] + " ");
}
}
}
2. 红包问题
需求:
给你两个整数M和N,M表示红包的总额, N表示红包的个数
现在又N个人来抽红包,每个人都是随机的,打印每个人领的红包金额
思路
本道题不是单纯随机就可以的,假设200元5个红包,直接5次随机有可能会遇到很多问题:
-
前面的人把钱都领完了,后面的人领不到了
-
5个人随机的总额不是红包总额
注意本题的几个坑:
-
每个人最少1分钱
-
每个人领完红包之后,至少预留 1 * N 分钱
第一个人:至少预留4分钱
第二个人:至少预留3分钱
第三个人:至少预留2分钱
第四个人:至少预留1分钱
- 最后一个人是拿剩余的总额,不随机
代码
java
package unit7;
import java.util.Random;
import java.util.Scanner;
/**
* 红包分配程序
* 该程序模拟了多个用户分配固定金额的红包场景
*/
public class text2 {
//看课学习
public static void main(String[] args){
// 创建Scanner对象用于接收用户输入
Scanner sc = new Scanner(System.in);
// 获取用户输入的金额m(元)和人数n
int m = sc.nextInt();
int n = sc.nextInt();
// 判断红包总金额是否足够分配
if(m*100 < n){
// 金额不足时提示用户充值
System.out.println("红包金额不足,请充值~");
return; // 终程序执行
}
// 创建随机数生成器
Random r = new Random();
// 将金额转换为分(单位:分)
int mm = m*100;
// 循环分配红包,前n-1个人
for(int i = 1; i < n; i++){
// 生成随机金额(确保剩余金额足够分配)
int num = r.nextInt(mm-(n-i))+1;
// 输出当前用户领取的金额(转换为元)
System.out.printf("第%d个人领取了%.2f元\n", i, num*0.01);
// 减去已分配的金额
mm -= num;
}
// 最后一个人领取剩余的全部金额
System.out.printf("第%d个人领取了%.2f元\n", n, mm*0.01);
}
}
3. 中位数
给定两个正序数组 arr1和 arr2,请先合并数组,并找出合并之后数组的中位数。
举例:
1 2 3 4 5 6 7 8 9 中位数:5
1 2 3 4 5 6 中位数: ( 3 + 4 ) / 2
思路
排序
代码
java
package unit7;
import java.util.Scanner;
import static java.util.Arrays.sort;
/**
* 合并两个数组并找出中位数的程序
* 该程序通过用户输入两个数组,合并后排序,最后计算并输出中位数
*/
public class text3 {
/**
* 主方法,用于执行程序逻辑
*/
static void main() {
//合并两个数组并找出中位数
// 创建Scanner对象用于接收用户输入
Scanner sc = new Scanner(System.in);
// 提示用户输入第一个数组的长度
System.out.println("请输入第一个数组的长度:");
// 读取第一个数组的长度
int n1 = sc.nextInt();
// 创建第一个数组
int[] arr1 = new int[n1];
// 提示用户输入第一个数组的内容
System.out.println("请输入第一个数组:");
// 循环读取第一个数组的元素
for(int i = 0; i < n1; i++) arr1[i] = sc.nextInt();
// 提示用户输入第二个数组的长度
System.out.println("请输入第二个数组的长度:");
// 读取第二个数组的长度
int n2 = sc.nextInt();
// 创建第二个数组
int[] arr2 = new int[n2];
// 提示用户输入第二个数组的内容
System.out.println("请输入第二个数组:");
// 循环读取第二个数组的元素
for(int i = 0; i < n2; i++) arr2[i] = sc.nextInt();
// 创建合并后的数组,长度为两个数组长度之和
int[] arr = new int[n1 + n2];
// 将第一个数组的元素复制到合并数组中
for(int i = 0; i < n1; i++) arr[i] = arr1[i];
// 将第二个数组的元素复制到合并数组中
for(int i = 0; i < n2; i++) arr[n1 + i] = arr2[i];
// 对合并后的数组进行排序
sort(arr);
// 输出中位数结果提示信息
System.out.println("合并后的数组的中位数为:");
if((n1 + n2) % 2 == 0) System.out.println((arr[(n1 + n2) / 2 - 1] + arr[(n1 + n2) / 2]) / 2.0);
else System.out.println(arr[(n1 + n2) / 2]);
}
}
4. 统计个数
学校选举学生会主席,有5个候选人
全校1000名同学参与投票(每人一票,可以弃权,或者选1-5号)。
投票使用Random模拟。0:弃权,1 ~ 5:给对应的候选人投票
要求1:
统计每个候选人的得票数和得票率,找出得票最多的候选人?
要求2:
统计弃票数和弃票率是多少?
思路
模拟即可
代码
java
package unit7;
import java.util.Random;
/**
* 这是一个模拟投票程序的类,用于统计5个候选人的得票情况以及弃票情况
*/
public class text4 {
/**
* 主方法,用于执行投票统计逻辑
*/
static void main() {
int people = 5; // 候选人数量
int student = 1000; // 总投票人数
// 创建一个长度为6的数组,用于存储0-5号选项的票数(0代表弃票,1-5代表候选人)
int[] num = new int[6];
// 创建随机数生成器
Random r = new Random();
// 循环模拟1000人投票
for(int i = 0; i < student; i++) {
// 生成0-5之间的随机数,模拟投票选择
int n = r.nextInt(6);
// 对应选项的票数加1
num[n]++;
}
// 遍历1-5号候选人,输出各自的得票数和得票率
for(int i= 1; i <= 5; i++){
//输出得票数与得票率,保留两位小数
System.out.printf("第%d号得票数:%d,得票率:%.2f%%\n", i, num[i], num[i] * 100.0 / student);
}
//输出弃票数与弃票率
System.out.printf("弃票数:%d,弃票率:%.2f%%\n", num[0], num[0] * 100.0 / student);
}
}
5. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
代码
java
package unit7;
import java.util.Scanner;
import static java.lang.Math.min;
//给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水
//运用动态规划的思想
public class text5 {
/**
* 主方法,用于计算接雨水的总量
*/
static void main() {
// 创建Scanner对象用于读取用户输入
Scanner sc = new Scanner(System.in);
// 读取数组长度n
int n = sc.nextInt();
// 创建长度为n的数组arr用于存储高度值
int[] arr = new int[n];
// 循环读取n个高度值存入数组arr
for (int i = 0; i < n; i++) arr[i] = sc.nextInt();
// 创建left数组用于存储每个位置左边的最大值
int[] left = new int[n];
// 创建right数组用于存储每个位置右边的最大值
int[] right = new int[n];
// 初始化left数组的第一个元素
left[0] = arr[0];
// 初始化right数组的最后一个元素
right[n - 1] = arr[n - 1];
// 从左向右遍历,计算每个位置左边的最大值
for (int i = 1; i < n; i++){
left[i] = max(left[i - 1], arr[i]);
}
// 从右向左遍历,计算每个位置右边的最大值
for (int i = n - 2; i >= 0; i--) {
right[i] = max(right[i + 1], arr[i]);
}
// 初始化总和为0
int sum = 0;
// 计算每个位置能接到的雨水量并累加到sum中
for (int i = 0; i < n; i++) {
sum += min(left[i], right[i]) - arr[i];
}
// 输出总雨水量
System.out.println(sum);
}
/**
* 辅助方法,返回两个整数中的较大值
* a 第一个整数
* b 第二个整数
* a和 b中的较大值
*/
static int max(int a, int b) {
return a > b ? a : b;
}
}
6. 大乐透
需求:
号码介绍:
大乐透选号规则明确规定:同一投注区内的号码不可重复,但不同投注区之间允许号码重复。具体规则可分为前区和后区两个维度:
大乐透选号重复规则详解
1.前区号码不可重复。
-
投注范围:从01-35中选择5个号码。
-
规则要求:所选5个号码之间不可出现重复数字,如出现重复则该注视为无效投注。
2.后区号码不可重复。
-
投注范围:从01-12中选择2个号码。
-
规则要求:所选2个号码之间不可重复,否则同样视为无效投注。跨区重复规则。
前区与后区号码允许交叉重复,例如前区选10,后区也可选10。系统自动判定:跨区重复不会触发错误提示,属于有效投注。
玩法知识延伸
基本结构:采用"5+2"双区投注模式,前区35选5与后区12选2组合形成完整投注号码。
无效投注判定:同一区内重复号码在开奖前会被系统自动识别为无效票,无法参与兑奖。
策略提醒:虽然跨区重复有效,但统计显示前区与后区号码重复率仅3.8%,建议选号时优先考虑号码分布合理性。
中奖规则:

代码
java
package unit7;
import java.util.Random;
import java.util.Scanner;
public class text6 {
/*
* 彩票规则:
* 前区: 1~35 选5个号码(唯一)
* 后区: 1~12 选2个号码(唯一)
* 跨区域可重复
* * 中奖规则:
* 一等奖: 5+2
* 二等奖: 5+1
* 三等奖: 5+0/4+2
* 四等奖: 4+1/3+2
* 五等奖: 4+0/3+1/2+2
* 六等奖: 3+0/2+1/1+2/0+2
* * 1. 利用Random随机, 生成彩票号码
* 2. 利用Scanner模拟购买彩票
* 3. 判断中奖
* */ static void main() {
//1. 利用Random随机, 生成彩票号码
int[] lotteryNumber = creatLotteryNumber();
printLotteryNumber(lotteryNumber);
//2. 利用Scanner模拟购买彩票
int[] myLotteryNumber = buyLotteryNumber();
printLotteryNumber(myLotteryNumber);
//3. 判断中奖
//判断中了几个前区(红球)
//判断中了几个后区(蓝球)
//注意:与顺序无关
getWinnerNumber(lotteryNumber, myLotteryNumber);
}
//arr1为彩票号码, arr2为购买号码
public static void getWinnerNumber(int[] arr1, int[] arr2){
int count = 0;
//前区
count = getCount(arr2[0], arr1, 0, 4);
System.out.println("中了" + count + "个红球");
//后区
int count2 = 0;
count2 = getCount(arr2[5], arr1, 5, 6);
System.out.println("中了" + count2 + "个蓝球");
//判断中奖
if(count == 5 && count2 == 2){
System.out.println("恭喜你中了一等奖");
}else if((count == 5 && count2 == 1) || (count == 4 && count2 == 2)){
System.out.println("恭喜你中了二等奖");
}else if((count == 5 && count2 == 0) || (count == 4 && count2 == 0) || (count == 4 && count2 == 1) || (count == 3 && count2 == 2)){
System.out.println("恭喜你中了三等奖");
}else if((count == 4 && count2 == 0) || (count == 3 && count2 == 1) || (count == 3 && count2 == 0) || (count == 2 && count2 == 2) || (count == 1 && count2 == 2) || (count == 0 && count2 == 2)){
System.out.println("恭喜你中了四等奖");
}else if((count == 4 && count2 == 0) || (count == 3 && count2 == 1) || (count == 3 && count2 == 0) || (count == 2 && count2 == 2) || (count == 1 && count2 == 2) || (count == 0 && count2 == 2)){
System.out.println("恭喜你中了五等奖");
}else if((count == 3 && count2 == 0) || (count == 2 && count2 == 1) || (count == 1 && count2 == 2) || (count == 0 && count2 == 2)){
System.out.println("恭喜你中了六等奖");
}else if(count == 0 && count2 == 0){
System.out.println("恭喜你,没有中奖");
}
}
//判断前区或后区中了几个球
public static int getCount(int number, int[] arr, int start, int end){
int count = 0;
for (int i = start; i <= end; i++) {
boolean flag = contains(number, arr, start, end);
if(flag){
count++;
}
}
return count;
}
public static int[] buyLotteryNumber(){
//1.创建数组
int[] arr = new int[7];
//2.利用Scanner, 生成前区彩票号码
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 5; ) {
System.out.println("请输入第" + (i+1) + "个前区号码(1~35):");
int number = sc.nextInt();
//范围判断
if (number < 1 || number > 35){
System.out.println("当前彩票号码不在范围当中,请重新选择");
continue;
}
//判断number是否唯一
boolean flag = contains(number, arr, 0 , 4);
if(flag){
System.out.println("当前彩票号码重复,请重新选择");
continue;
}
if(!flag) {
arr[i] = number;
i++;
}
}
//3.利用Scanner, 生成后区彩票号码
for (int i = 5; i < arr.length; ) {
System.out.println("请输入第" + (i+1) + "个后区号码(1~12):");
int number = sc.nextInt();
//范围判断
if (number < 1 || number > 12){
System.out.println("当前彩票号码不在范围当中,请重新选择");
continue;
}
//判断number是否唯一
boolean flag = contains(number, arr, 5, 6);
if(flag){
System.out.println("当前彩票号码重复,请重新选择");
continue;
}
if(!flag) {
arr[i] = number;
i++;
}
}
return arr;
}
public static int[] creatLotteryNumber(){
//1.创建数组
int[] arr = new int[7];
//2.利用Random随机, 生成前区彩票号码
Random r = new Random();
for (int i = 0; i < 5; ) {
int number = r.nextInt(1,36);
//判断number是否唯一
boolean flag = contains(number, arr, 0 , 4);
if(!flag){
arr[i] = number;
i++;
}
}
//3.利用Random随机, 生成后区彩票号码
for (int i = 5; i < arr.length; ) {
int number = r.nextInt(1,13);
//判断number是否唯一
boolean flag = contains(number, arr, 5, 6);
if(!flag){
arr[i] = number;
i++;
}
}
return arr;
}
public static boolean contains(int number, int[] arr, int start, int end){
for (int i = start; i <= end; i++) {
if (number == arr[i]){
return true;
}
}
return false;
}
public static void printLotteryNumber(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}