一、代码题
1.爬楼梯
(1)题目
假设你正在爬楼梯。需要n阶你才能到达楼顶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?
- 示例 1: 输入:n=2 输出:2
- 解释:有两种方法可以爬到楼顶。 1阶+1阶 2 阶
- 示例 2: 输入:n=3 输出:3
- 解释:有三种方法可以爬到楼顶。 1 阶+1阶+1阶 1 阶 +2 阶 2 阶+1阶
(2)思路实现
问题的核心在于找到到达第 n 阶的方法数。每次你可以爬 1 或 2 个台阶,因此到达第 n 阶的方法数等于到达第 n-1 阶的方法数加上到达第 n-2 阶的方法数。这是因为从第 n-1 阶爬 1 个台阶可以到达第 n 阶,从第 n-2 阶爬 2 个台阶也可以到达第 n 阶。
(3)代码实现
package com.thor.test;
public class Demo {
public static void main(String[] args) {
//创建Solution对象的实例
Solution solution = new Solution();
//示例 1: 输入:n=2 输出:2 解释:有两种方法可以爬到楼顶。1阶+1阶 2阶
int i = solution.climbStairs(2);
System.out.println(i);
//示例 2: 输入:n=3 输出:3 解释:有三种方法可以爬到楼顶。 1阶+1阶+1阶 1阶+2阶 2阶+1阶
int i1 = solution.climbStairs(3);
System.out.println(i1);
}
}
class Solution {/**
* @description:
* @author: Allen
* @date: 2025/1/13 15:18
* @param: [n] n为n层台阶
* @return:
**/
public int climbStairs(int n){
//此时n为0或1,直接返回1,因为只有一种方法可以到达
if(n<=1){
return 1;
}
//创建一个数组dp,用于存储到达每一阶的方法数
int[] dp= new int[n+1];
//初始化dp[0] dp[1] 因为到达第0阶和第1阶的方法数都是1
dp[0]=1;
dp[1]=1;
//使用循环计算从第2阶到n阶的方法数
for(int i=2;i<=n;i++){
//状态转移方程
dp[i]=dp[i-1]+dp[i-2];
}
//返回到达第n阶的方法数
return dp[n];
}
}
2.删除排序链表中的重复元素
(1)题目
给定一个已排序的链表的头head,删除所有重复的元素,使每个元素只出现一次。返回已排序的链表
示例 1: 输入:head =[1,1,2] 输出:[1,2]
示例 2: 输入:head =[1,1,2,3,3] 输出:[1,2,3]
(2)思路实现
1. 从链表的头节点开始遍历。
2. 对于每个节点,检查其值是否与下一个节点的值相同。
3. 如果相同,则跳过下一个节点,即将当前节点的 next 指针指向下一个节点的下一个节点。
4. 如果不同,则继续遍历下一个节点。
5. 重复上述步骤直到遍历完整个链表。
6. 返回处理后的链表头节点。
(3)代码实现
package com.thor.test;
public class Demo {
public static void main(String[] args) {
// 创建 Solution 对象
ListNode.Solution solution = new ListNode.Solution();
// 示例 1: 输入: head = [1,1,2] 输出: [1,2]
ListNode l1 = new ListNode(1, new ListNode(1, new ListNode(2)));
ListNode listNode = solution.deleteDuplicates(l1);
System.out.print("示例1输出:");
printList(listNode);
// 示例 2: 输入: head = [1,1,2,3,3] 输出: [1,2,3]
ListNode l2 = new ListNode(1, new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(3)))));
ListNode listNode1 = solution.deleteDuplicates(l2);
System.out.print("示例2输出:");
printList(listNode1);
}
// 打印链表的辅助方法
public static void printList(ListNode head) {
ListNode current = head;
while (current != null) {
System.out.print(current.val + " ");
current = current.next;
}
System.out.println();
}
}
class ListNode {
/**
* @description:
* @author: Allen
* @date: 2025/1/13 17:19
* @param:
* @return:
**/
int val; // 节点值
ListNode next; // 下一个节点
ListNode() {} // 无参构造方法
ListNode(int val) { this.val = val; } // 有参构造方法
ListNode(int val, ListNode next) { this.val = val; this.next = next; } // 有参构造方法
static class Solution {
/**
* @description:
* @author: Allen
* @date: 2025/1/13 16:50
* @param: [head] // 链表头节点
* @return:
**/
public ListNode deleteDuplicates(ListNode head) {
// 初始化当前指针指向链表头节点
ListNode current = head;
// 遍历链表,当前节点和下一个节点都不为 null
while (current != null && current.next != null) {
// 如果当前节点的值和下一个节点的值相同
if (current.val == current.next.val) {
// 跳过下一个节点,当前节点的 next 指向下一个节点的下一个节点
current.next = current.next.next;
} else {
// 如果当前节点的值和下一个节点的值不同,则指针后移一位
current = current.next;
}
}
// 返回处理后的链表头节点
return head;
}
}
}
二、数组
1.使用
- 格式:数据类型 [] 变量名 = new 数据类型 [ 长度 ]————动态初始化
- 数据类型 [] 变量名={数值 1,数值 2,数值 3......}————静态初始化
- 赋值:变量名 [序号] = 数值
- 代码
//数组格式
int [] arr= new int[5];
//赋值
arr[0]=1;
arr[1]=2;
arr[2]=3;
arr[3]=4;
arr[4]=5;
//输出
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
2.length
(1)属性和方法的区别
- 有小括号叫方法——length()
- 无小括号叫属性——length
(2)使用
- 快速使用:arr.for 或者 arr.fori
- 代码
int[]arr= {1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
(3)练习题
a.题目:有一个数列:8,4,2,1,23,344,12。
- 循环输出数列的值
- 求数列中所有数值的和
- 猜数游戏:从键盘中任意输入一个数据,判断数列中是否包含此数
补充知识点:三目运算符 ——这里的 condition
是一个布尔表达式,如果它的值为 true
,则整个表达式的结果为 value1
;如果为 false
,则结果为 value2
。
代码
Scanner scanner = new Scanner(System.in);
int[]arr= {8,4,2,1,23,344,12};
int sum= 0;
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
sum+=arr[i];
}
System.out.println("\n"+"和:"+sum);
System.out.print("请输入一个数: ");
int number = scanner.nextInt();
boolean flag= false;
for (int i = 0; i < arr.length; i++) {
if(number==arr[i]){
flag=true;
break;
}
}
System.out.println(flag?"存在":"不存在");
b.题目:从表格的形式输出5笔购物金额及总金额
实现步骤:
- 创建一个长度为5的double类型数组,存储购物金额
- 循环输入5笔购物金额,并累加总金额
- 利用循环输出5笔购物金额最后输出总金额
代码
Scanner scanner = new Scanner(System.in);
double [] arr = new double[5];
System.out.println("消费记录");
for (int i = 0; i < arr.length; i++) {
System.out.print("请输入第"+(i+1)+"笔购物金额: ");
arr[i] = scanner.nextDouble();
}
System.out.println("序号\t金额");
double sum = 0;
for (int i = 0; i < arr.length; i++) {
System.out.println((i+1)+"\t"+arr[i]);
sum+=arr[i];
}
System.out.println("总金额: "+sum);
三、 Array类
- 提供了很多操作数组的方法
1.sort——排序(升序)
int[]arr={1,4,7,3,2};
Arrays.sort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
2.to String——将数组转换成字符串
int[]arr={1,4,7,3,2};
System.out.println(Arrays.toString(arr));
3.equals——boolean equals(array1,array2):比较array1和array2两个数组是否相等
int[]arr1={1,4,7,3,2};
int[]arr2={1,4,7,3,2};
System.out.println(Arrays.equals(arr1,arr2));
4.fill——void fill(array,val):把数组array所有元系都赋值为val
int[]arr1={1,4,7,3,2};
Arrays.fill(arr1,12);
System.out.println(Arrays.toString(arr1));
5.copyOf——copy0f(array,length):将数组array复制成一个长度为length的新数组,返回类型与复制的数组一致
空位置默认为 0
int[]arr1={1,4,7,3,2};
System.out.println( Arrays.toString(Arrays.copyOf(arr1,6)));
练习题
题目:将 一组乱序的字符(a、d、r、t、y、u、h)进行排序进行升序和逆序输出
实现步骤:
- 创建数组存储原字符序列
- 利用Arrays类的sort()方法对数组进行排序,并循环输出
- 从最后一个元素开始,将数组中的元素逆序输出
代码
char [] arr ={'a','d','r','t','y','u','h'};
System.out.print("原字符系列: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
Arrays.sort(arr);
System.out.println();
System.out.print("升序排序后: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
System.out.print("逆序输出后: ");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
四、练习题
1.二重循环
题目:若有3个班级各4名学员参赛,如何计算每个班级参赛学员的平均分?
思路:外层循环控制班级数目,内层循环控制每个班级学员数目
代码:
Scanner scanner = new Scanner(System.in);
//外循环班级,内循环学生
for (int i = 1; i <= 3; i++) {
System.out.println("第输入第" + i + "个班级的成绩");
int sum = 0;
for (int j = 1; j <= 4; j++) {
System.out.print("第" + j + "个学生的成绩: ");
sum+=scanner.nextInt();
}
System.out.println("第" + i + "个班级的平均成绩是: " + sum/4.0);
}
2.正方形
for (int i = 0; i <=5; i++) {
for (int j = 0; j <= 5; j++) {
System.out.print("*"+" ");
}
System.out.println();
}
3.直角三角形
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
4.倒直角三角形
for (int i = 1; i <= 5; i++) {
for (int j = 0; j < 5 - i; j++) {
System.out.print("*");
}
System.out.println();
}
5.等腰三角形
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5 - i; j++) {
System.out.print(" ");
}
for (int k = 1; k <= 2 * i - 1; k++) {
System.out.print("*");
}
System.out.println();
}
6.九九乘法表
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + (i * j) + "\t");
}
System.out.println();
}
7.冒泡排序
int[] arr = {1, 3, 5, 7, 9, 2, 4, 6, 8, 0};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// 交换 arr[j] 和 arr[j + 1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
// 打印排序后的数组的每个元素
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]); // 只打印当前元素,而不是整个数组
}
// 如果你还想打印整个排序后的数组,可以这样做一次:
System.out.println(Arrays.toString(arr)); // 打印整个排序后的数组一次
五、二维数组
1.格式
- int[ ][ ] arr = new int [ ][ ]
2.代码
int[][]arr={
{1,2,3},
{4,5,6},
{7,8,9}
};
//二重循环
//外循环:行数 内循环:行的元素
for (int i = 0; i < arr.length; i++) {
for(int j = 0; j <arr[i].length ; j++){
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}
六、函数
1.有无返回值、参数
public static void main(String[] args) {
//无参无返
f01();
//无参有返
f02();
int i = f02();
System.out.println("返回的值: "+i);
//有参无返
f03("allen", 18);
//有参有返
f04("allen", 18);
System.out.println("返回的值: "+i);
}
/*
* @description: 公共的访问修饰符public 静态的static 没有返回值的void 方法名(参数列表){ 方法体 }
* @author: Allen
* @date: 2025/1/19 20:21
* @param:
* @return:
*/
public static void f01(){
System.out.println("f01\n");
}
/*
* @description: 公共的访问修饰符public 静态的static 有返回值的int 方法名(参数列表){ 方法体 return 数字 }
* @author: Allen
* @date: 2025/1/19 20:23
* @param:
* @return:
*/
public static int f02(){
System.out.println("f02");
return 0;
}
/*
* @description: 公共的访问修饰符public 静志的static 没有返回值的void 方法名(参数列表){ 方法体 return 数字;} 有参无返
* @author: Allen
* @date: 2025/1/19 20:27
* @param:
* @return:
*/
public static void f03(String name,int age){
System.out.println("\n"+name);
System.out.println(age+"\n");
}
/*
* @description: 公共的访问修饰符public 静志的static 有返回值的int 方法名(参数列表){ 方法体 return 数字;} 有参有返
* @author: Allen
* @date: 2025/1/19 20:34
* @param:
* @return:
*/
public static int f04(String name,int age){
System.out.println(name);
System.out.println(age);
return 1;
}
2.函数重载
- 什么是:函数支持同名
- 原则:方法名相同,参数列表不相同,与返回值无关
代码
public static void main(String[] args) {
f01(1);
f01(1.0);
}
public static void f01(double money){
System.out.println("1");
}
public static int f01(int age){
System.out.println(age);
return age;
}
3.函数可变个数参数
public static void main(String[] args) {
f01(new int[]{1,2,3});
f01();
f01(1);
f01(1,2);
f01(1,2,3);
f01(1,2,3,4);
}
public static void f01(int... x){
System.out.println(Arrays.toString(x));
}
4.foreach——增加和简化for循环
- foreach 输出,没有下标
public static void main(String[] args) {
f01(new int[]{1,2,3});
f01();
f01(1);
f01(1,2);
f01(1,2,3);
f01(1,2,3,4);
}
public static void f01(int... arr){
for (int i : arr) {
System.out.print(i);
}
}
5.传参
- 基本数据类型
public static void main(String[] args) {
int x=10;
f01(x);
}
public static void f01(int y){
System.out.println(y);
y++;
System.out.println(y);
}
- 引用数据类型
public static void main(String[] args) {
int [] x={10,20,30};
f01(x);
System.out.println(Arrays.toString(x));
}
public static void f01(int[] y){
System.out.println(Arrays.toString(y));
y[0]++;
System.out.println(Arrays.toString(y));
}