刷题小记:
本期涉及ACM模式下栈和链表的构建与使用,值得学习。
卡玛网15.神秘字符(卡玛网15.神秘字符)
题目分析:
若给定2行字符串,其中第一个串的长度为偶数,现要求把第二个串插入到第一个串的正中央并输出。
输入数据首先给出一个整数n,表示测试数据的组数,每组2行,每行一个字符串,长度大于0小于50,每组第一行的字符串的长度必为偶数。
输出时每组输出占一行即可。
解题思路:
分组读入,借助StringBuilder构造。
import java.util.*;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNext()) { // 处理多组输入int n = in.nextInt();in.nextLine(); // 消耗换行符while (n-- > 0) {String s1 = in.nextLine();String s2 = in.nextLine();StringBuilder sb = new StringBuilder(s1);sb.insert(sb.length() / 2, s2);System.out.println(sb.toString());}}in.close();}
}
卡码网16.位置互换(卡码网16.位置互换)
题目分析:
输入包含多组测试数据,第一行是一个整数n,表示有且只有n组测试数据,每组测试数据为一行长度为偶数的字符串(串长不超过50)。
请为每组测试数据输出奇偶位互换后的结果,每组输出占一行。
解题思路:
借助StringBuilder进行构造,每2个字符一对遍历字符串,每对字符使用Swap进行交换(添入StringBuilder的次序交换)。
import java.util.*;
public class Main{public static void main(String[] args) {Scanner in = new Scanner(System.in);while(in.hasNext()) {int n = in.nextInt();in.nextLine();// 消耗换行符while(n-- > 0) {String s = in.nextLine();StringBuilder sb = new StringBuilder();for(int i = 0; i < s.length(); i+=2) {sb.append(s.charAt(i+1));sb.append(s.charAt(i));}System.out.println(sb.toString());}}in.close();}
}
卡玛网17.出栈合法性(卡玛网17.出栈合法性)
题目分析:
已知自然数1,2,......,N(1 <= N <= 100)依次入栈,请问接下来的各组序列是否为合法的出栈序列。
输入包含多组测试数据。每组测试数据的第一行为整数N,当N = 0时输入结束;第二行为N个正整数,以空格隔开,为出栈序列。
输出Yes或No表示每组出栈序列是否合法。
解题思路:
观察示例可以发现:出栈序列并非先将所有1~N的自然数入栈后再出栈,而是边入栈边适时按出栈序列出栈。
- 以3 4 2 1 5为例:
-
- 1入栈,2入栈,3入栈,3出栈—— 12
- 4入栈,4出栈—— 12
- 2出栈—— 1
- 1出栈—— 栈空
- 5入栈,5出栈——栈空
- 这是合法的。
- 以3 5 1 4 2为例:
-
- 1入栈,2入栈,3入栈,3出栈—— 12
- 4入栈,5入栈,5出栈—— 124
- 1出栈——124,栈顶为4,无法实现
- 这是不合法的。
解题步骤:
观察两个示例可以发现解题步骤如下:
- 将i属于1~N的自然数依次入栈,且从j = 0处开始遍历出栈序列
- 每次先将i入栈,再循环检查栈顶元素top与出栈序列下标j处的curNum
-
- 若相同,则top出栈,j++
- 若不相同,结束循环
- 入栈序列全部完毕,栈不为空,那么结果为No。
import java.util.*;
public class Main{public static void main(String[] args){Scanner in = new Scanner(System.in);while(in.hasNext()){int N = in.nextInt();if (N == 0) break;in.nextLine();// 消耗换行符String[] popList = in.nextLine().split(" ");String res;Deque<Integer> stack = new ArrayDeque<>();for(int i = 1, j = 0; i <= N; i++) {stack.push(i);// 依次入栈while(j < N && !stack.isEmpty()) {// 依次出栈int top = stack.peek();int curNum = Integer.parseInt(popList[j]);if (top == curNum) {stack.pop();j++;} else {break;}}}if (stack.isEmpty()) res = "Yes";else res = "No";System.out.println(res);}in.close();}
}
卡码网18.链表的基本操作(卡码网18.链表的基本操作)
题目分析:
按要求实现链表及其基本操作
输入描述:
输入数据只有一组,第一行有n+1个整数,第一个整数是这行余下的整数数目n,后面是n个整数,用于初始化链表,且输入的顺序与链表中的顺序相反。
第二行有一个整数m,表示接下来有m行,每行有一个字符串代表对链表的操作。
输出描述:
每个操作的含义及其对应的输出如下:
- "get",代表获得第a个元素(a从1开始计数)
-
- 获取成功则输出该元素
- 获取失败则输出"get fail"
- "delete",代表删除第a个元素(a从1开始计数)
-
- 删除成功则输出"delete OK"
- 删除失败则输出"delete fail"
- "insert",其后跟着两个用空格隔开的整数a和e,代表在第a个位置前面插入e(a从1开始计数)
-
- 插入成功则输出"insert OK"
- 插入失败则输出"insert fail"
- "show",直接打印链表全部内容
-
- 链表不为空,用空格间隔输出链表中的全部元素
- 链表为空,输出"Link list is empty"
解题思路:
头插法实现倒序插入。
按要求初始化自定义链表的数据结构及其操作。
注意:
- insert方法在a为链表长度加1时,表示在链表末尾插入,若a超过此值,则插入失败。
- insert方法和delete方法可能改变头节点,需特殊处理(或者给链表增设虚拟头节点dumpyHead以解决该问题)
import java.util.*;
public class Main{static class ListNode{int val;ListNode next;public ListNode() {}public ListNode(int val) {this.val = val;this.next = null;}public ListNode(ListNode next) {this.next = next;}public ListNode(int val, ListNode next) {this.val = val;this.next = next;}}static class MyLinkedList{ListNode head;public MyLinkedList() {this.head = null;};public void add(int val) {// 头插法实现倒序地添加元素head = new ListNode(val, head);}public String get(int a) {ListNode cur = head;int num = 1;while(cur.next != null && num != a) {cur = cur.next;num++;}if (num == a) return Integer.toString(cur.val);else return "get fail";}public String delete(int a) {if (a == 1) {// 特殊处理a为1时的情况,更新头节点if (head != null) {head = head.next;return "delete OK";}else {return "delete fail";}}ListNode pre = new ListNode(head);int num = 1;while(pre.next != null && num != a) {pre = pre.next;num++;}if (pre.next != null && num == a) {pre.next = pre.next.next;return "delete OK";}else {return "delete fail";}}public String insert(int a, int e) {if (a == 1) {// 特殊处理a为1时的情况,更新头节点if (head == null) {head = new ListNode(e);} else {head = new ListNode(e, head);}return "insert OK";}ListNode pre = new ListNode(head);int num = 1;while(pre.next != null && num != a) {pre = pre.next;num++;}if (num == a) {pre.next = new ListNode(e, pre.next);return "insert OK";} else {return "insert fail";}}public String show() {StringBuilder sb = new StringBuilder();ListNode cur = head;while(cur != null) {if (cur != head) sb.append(" ");sb.append(cur.val);cur = cur.next;}if (sb.length() > 0) return sb.toString();else return "Link list is empty";}}public static void main(String[] args) {Scanner in = new Scanner(System.in);MyLinkedList list = new MyLinkedList();while(in.hasNext()) {int n = in.nextInt();while(n-- > 0) {int val = in.nextInt();list.add(val);}int m = in.nextInt();in.nextLine();// 消耗换行符while(m-- > 0) {String[] opt = in.nextLine().split(" ");switch (opt[0]) {case "get":System.out.println(list.get(Integer.parseInt(opt[1])));break;case "delete":System.out.println(list.delete(Integer.parseInt(opt[1])));break;case "insert":System.out.println(list.insert(Integer.parseInt(opt[1]), Integer.parseInt(opt[2])));break;case "show":System.out.println(list.show());break;default:break;}}}in.close();}
}