Java训练题12

一、选择题

1、在单链表中,要将s所指结点插入到p所指结点之后,其语句应为(D )
A. s.next=p+1; p.next=s;
B. p.next=s; s.next=p.next
C. s.next=p.next; p.next=s.next;
D. s.next=p.next; p.next=s;
答案解析:D
把s指向的结点插入到p所指向的结点之后,首先要保证链表不断链,就需要先把s指向的结点和p后年的结点链接起来,代码为
s.next=p.next;
最后让p的下一个结点指向s即可,代码为p.next=s
2、下述有关栈和队列的区别,说法错误的是 (D )
A. 栈是限定只能在表的一端进行插入和删除操作。
B. 队列是限定只能在表的一端进行插入和在另一端进行删除操作。
C. 栈和队列都属于线性表
D. 栈的插入操作时间复杂度都是o(1),队列的插入操作时间复杂度是o(n)
答案解析:D
栈的插入操作时间复杂度都是o(1),因为栈只允许在表的某一端进行操作
队列的插入操作时间复杂度是o(1),队列的入队操作也只允许在表的其中一端
3、输入序列是ABC,输出序列变为BCA时,经过的栈操作为(B )
A. push,push,push,pop,pop,pop
B. push,push,pop,push,pop,pop
C. push,pop,push,push,pop,pop
D. push,push,pop,pop,push,pop
答案解析:B
上题中,整个入栈和出栈的过程可以为,A先入栈(push),B入栈(push),B出栈(pop),C入栈(push),C出栈
(pop),A出栈(pop),所以整个过程为:push,push,pop,push,pop,pop
4、栈的特点是先入先出,这种说法(B )
A. 正确 B. 错误
答案解析:B
说法错误。栈的特点为先入后出
5、一个队列的入队序列为 1234 ,则队列可能的输出序列是(A )
A. 4321
B. 1234
C. 1432
D. 3241
答案解析:B
队列的特点是先入先出原则,入队顺序为1234,那么出队顺序和入队顺序是一样的

二、编程题

1、合并链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。OJ链接

示例1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例2:
输入:l1 = [], l2 = [0]
输出:[0]

【解题思路】:
这道题目课上反复讲过,一共有两种思路来解决。
1.递归法,利用好方法的语义,判断当前l1和l2的头结点的大小,将剩余结点和另外整个链表的合并操作交给子函数处理。
2.原地移动,在遍历l1和l2的时候尾插新的合并链表。

class Solution {
// 1.递归法
	public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
		if (list1 == null) {
			return list2;
		}
		if (list2 == null) {
			return list1;
		}
		if (list1.val <= list2.val) {
		// 说明此时要把list1.next和整个list2交给merge
		// 然后将结果拼接到list1.next
		list1.next = mergeTwoLists(list1.next,list2);
		return list1;
		}else {
			list2.next = mergeTwoLists(list1,list2.next);
			return list2;
		}
	}
	// 2.原地移动
	public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
		// 边界
		if (list1 == null) {
			return list2;
		}
		if (list2 == null) {
			return list1;
		}
		// 此时l1和l2都不为空
		ListNode dummyHead = new ListNode(101);
		ListNode last = dummyHead;
		while (list1 != null && list2 != null) {
			if (list1.val <= list2.val) {
				last.next = list1;
				last = list1;
				list1 = list1.next;
			}else {
				last.next = list2;
				last = list2;
				list2 = list2.next;
			}
		}
		// 此时l1或l2为空
		if (list1 == null) {
			last.next = list2;
		}else {
			last.next = list1;
		}
		return dummyHead.next;
	}
}

2、删除链表中重复的结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5 OJ链接

示例1:
输入:{1,2,3,3,4,4,5}
返回值:{1,2,5}
示例2:
输入:{1,1,1,8}
输出:{8}

【解题思路】:
这道题难点有两个。1.如何判断重复结点(使用cur和next引用来判断),prev一定指向待删除结点的前驱(prev一定不是
待删除的结点)。2.删除多个重复结点(prev.next = next).

public class Solution {
	public ListNode deleteDuplication(ListNode pHead) {
		ListNode dummyHead = new ListNode(-1);
		dummyHead.next = pHead;
		ListNode prev = dummyHead;
		ListNode cur = prev.next;
		while (cur != null) {
			ListNode next = cur.next;
			if (next == null) {
			// 当前链表只有一个结点
				return dummyHead.next;
			}else {
				if (cur.val != next.val) {
					prev = prev.next;
					cur = cur.next;
				}else {
					while (next != null && cur.val == next.val) {
							next = next.next;
					}
					// 此时next指向第一个不重复的结点
					prev.next = next;
					cur = next;
				}
			}
		}
		return dummyHead.next;
	}
}
### Java编程练习及其解决方案 以下是几个典型的Java编程练习,这些问涵盖了基础语法、控制流、数组操作以及面向对象的概念。每道目均提供了详细的说明和可能的解决方法。 #### 1. **计算两个整数的最大公约数** - **问描述**: 输入两个正整数 `a` 和 `b`,编写一个函数返回它们的最大公约数 (GCD)。 - **解决方案**: 使用欧几里得算法可以高效求解最大公约数[^1]。 ```java public class GCD { public static int gcd(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return Math.abs(a); } public static void main(String[] args) { System.out.println(gcd(48, 18)); // 输出: 6 } } ``` #### 2. **反转字符串** - **问描述**: 实现一个函数,接受一个字符串作为参数并将其字符顺序反转后返回。 - **解决方案**: 可以通过遍历字符串并将字符逐一加入新字符串的方式实现反转功能。 ```java public class ReverseString { public static String reverse(String str) { StringBuilder reversed = new StringBuilder(); for (int i = str.length() - 1; i >= 0; i--) { reversed.append(str.charAt(i)); } return reversed.toString(); } public static void main(String[] args) { System.out.println(reverse("hello")); // 输出: olleh } } ``` #### 3. **判断回文数** - **问描述**: 判断给定的整数是否是一个回文数(即从左到右读和从右到左读一样)。 - **解决方案**: 将数字转换成字符串形式后再比较其前后部分即可得出结论。 ```java public class PalindromeNumber { public static boolean isPalindrome(int num) { String s = Integer.toString(num); int n = s.length(); for (int i = 0; i < n / 2; i++) { if (s.charAt(i) != s.charAt(n - 1 - i)) { return false; } } return true; } public static void main(String[] args) { System.out.println(isPalindrome(121)); // 输出: true } } ``` #### 4. **冒泡排序** - **问描述**: 对一组无序的整数列表进行升序排列。 - **解决方案**: 冒泡排序是一种简单直观的排序算法,它重复地走访要排序的数据列,依次比较相邻元素,并交换位置直到序列有序为止。 ```java public class BubbleSort { public static void bubbleSort(int[] arr) { int n = arr.length; for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } public static void main(String[] args) { int[] array = {64, 34, 25, 12, 22, 11, 90}; bubbleSort(array); for (int value : array) { System.out.print(value + " "); } // 输出: 11 12 22 25 34 64 90 } } ``` --- ### 总结 上述练习覆盖了基本的逻辑运算、循环结构、条件分支语句等内容,适合初学者逐步掌握Java的核心概念和技术要点。完成这些练习有助于加深对语言特性的理解,并提高实际开发能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值