刚需import
import java.util.Scanner;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.ArrayList;
import java.util.List;
import java.lang.System;
import java.io.*;
import java.util.*;
input场景
场景一:第一行单个整型数字a,代表第二行有a个数字,第二行的数字以空格(或其它字符)分开,把第二行的数字放进数组里
import java.util.Scanner;
import java.util.Arrays;
import java.lang.System;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);//输入int a = in.nextInt();in.nextLine(); // 消除nextInt()留下的换行符 String b=null;while (in.hasNextLine()) {// 第二行扫描为String bb = in.nextLine(); }String[] c=b.trim().split(" ");//.trim()可以去掉,以空格切割b为String[] cint[] d=new int[a];//用a,在某些场合换成c.length更万能for(int i=0;i<a;i++){d[i]=Integer.parseInt(c[i]);//String[] c强制转为int[] d}for(int i=0;i<a;i++){System.out.println(d[i]);//换行输出d}}
}
场景二:延申自【场景一】,但没有第一行的a,去掉a相关,并直接一行以空格(或其它字符)分隔的数字,只需要用c.length换成a
不改了,直接看场景一的注释来改
场景三:延申自【场景一】,但第一行a代表接下去要扫多少行的数字(或字符串等),后面的a行,用while循环,每行先存为一个数组,然后统计里面出现c这个字母出现的频率
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int a = scanner.nextInt(); for (int t = 0; t < a; t++) {String b = scanner.next(); // 读取每一行内容char[] charArray = b.toCharArray();//字符串变字符数组int count = 0;for (char c : charArray) {if (c == 'c') {count++;}}System.out.println(count);}}
}
【场景三】注意:(数组改为ArrayList)的“第一行a代表接下去要扫多少行的数字”,说明如果后面跟着的不止a行,也可以输入
只是输入了a+n行,也只循环前a行内容。如果想要行多了或少了直接报错,而不输出任何循环行的答案,就应该使用ArrayList而不是数组,方便无限增加内容,在读取每一行时记录每行的字符计数,并在结束时检查总行数是否等于预期行数,如果不等于则输出错误信息。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int a = scanner.nextInt();int count_line = 0;List<Integer> row = new ArrayList<>();while (scanner.hasNext()) {String b = scanner.next(); // 读取每一行内容char[] charArray = b.toCharArray(); // 字符串变字符数组int count = 0;for (char c : charArray) {if (c == 'c') {count++;}}row.add(count);count_line++;}if (count_line == a) {// 如果行数正确,输出List内容for (int value : row) {System.out.println(value);}} else {System.out.println("行数不对");}}
}
场景四:延申自【场景二】,但不止一行,是两行未知且长度不同的、以空格(或其它字符)分隔的数字,扫描进两个数组
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);String b = null;//第一行while (in.hasNextLine()) {b = in.nextLine();break;//一行一行地while并break}String[] c = b.trim().split(" ");int a = c.length; // 根据元素的数量确定数组的大小int[] array1 = new int[a];for (int i = 0; i < a; i++) {array1[i] = Integer.parseInt(c[i]);} b = null;// 第二行while (in.hasNextLine()) {b = in.nextLine();break;}String[] d = b.trim().split(" ");int[] array2 = new int[d.length];for (int i = 0; i < d.length; i++) {array2[i] = Integer.parseInt(d[i]);}System.out.println("Array 1:");//换行输出第一个数组for (int i = 0; i < array1.length; i++) {System.out.println(array1[i]);}System.out.println("Array 2:");//换行输出第二个数组for (int i = 0; i < array2.length; i++) {System.out.println(array2[i]);}}
}
场景五:延申自【场景四】,但不止两行,是若干行未知且长度不同的、以空格(或其它字符)分隔的数字,
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);List<List<Integer>> numberList = new ArrayList<>();while (scanner.hasNextLine()) {String line = scanner.nextLine();String[] numbersAsString = line.split("\\s+"); // 分隔数字,这里使用空格分隔List<Integer> numbers = new ArrayList<>();for (String num : numbersAsString) {numbers.add(Integer.parseInt(num));}numberList.add(numbers);}// 输出ArrayList内容for (List<Integer> numbers : numberList) {for (int i = 0; i < numbers.size(); i++) {System.out.print(numbers.get(i));if (i < numbers.size() - 1) {System.out.print(" ");//防止每一行最后多输入一个空格}}System.out.println();}}
}
其它场景注意:
防止input出问题
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);try {} catch (Exception e) {System.out.println("Error reading input. Please provide valid input.");} finally {scanner.close();}}
}
好用的函数
函数一:输入一个字符串,判断需要按几遍大小写切换
private static int calculateKeyPresses(String s) {int keyPresses = 0;boolean capsLock = false;for (char c : s.toCharArray()) {if (Character.isUpperCase(c) != capsLock) { // 需要按下CapsLock键keyPresses++;capsLock = !capsLock;}keyPresses++;// 按下字母键}return keyPresses;
}
矩阵转换
import java.io.*;
import java.util.*;class Solution {public void myFunc(ArrayList<ArrayList<Integer>> arr) {int numRows = arr.size();int numCols = arr.get(0).size();for (int j = 0; j < numCols; j++) {for (int i = 0; i < numRows; i++) {System.out.print(arr.get(i).get(j));if (i < numRows - 1) {System.out.print(" ");}}System.out.println();}}
}public class Main {public static void main(String args[]) {Scanner cin = new Scanner(System.in);ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();while (cin.hasNextLine()) {ArrayList<Integer> row = new ArrayList<Integer>();String line = cin.nextLine();if (line.length() > 0) {String[] arrLine = line.split(" ");for (int i = 0; i < arrLine.length; i++) {row.add(Integer.parseInt(arrLine[i]));}arr.add(row);}}new Solution().myFunc(arr);}
}
搜索
深度优先搜索(DFS)
class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) {val = x;}
}public class DepthFirstSearch {public void dfs(TreeNode root) {if (root == null) {return;}System.out.print(root.val + " "); // 访问当前节点dfs(root.left); // 递归遍历左子树dfs(root.right); // 递归遍历右子树}public static void main(String[] args) {DepthFirstSearch dfs = new DepthFirstSearch();// 构建二叉树TreeNode root = new TreeNode(1);root.left = new TreeNode(2);root.right = new TreeNode(3);root.left.left = new TreeNode(4);root.left.right = new TreeNode(5);// 深度优先搜索dfs.dfs(root);}
}
广度优先搜索(BFS)
import java.util.LinkedList;
import java.util.Queue;public class BreadthFirstSearch {public void bfs(TreeNode root) {if (root == null) {return;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {TreeNode current = queue.poll();System.out.print(current.val + " "); // 访问当前节点if (current.left != null) {queue.offer(current.left); // 将左子节点加入队列}if (current.right != null) {queue.offer(current.right); // 将右子节点加入队列}}}public static void main(String[] args) {BreadthFirstSearch bfs = new BreadthFirstSearch();// 构建二叉树TreeNode root = new TreeNode(1);root.left = new TreeNode(2);root.right = new TreeNode(3);root.left.left = new TreeNode(4);root.left.right = new TreeNode(5);// 广度优先搜索bfs.bfs(root);}
}
排序算法
排序算法是一类将一组元素按照特定顺序重新排列的算法。以下是一些常见的排序算法:
- 冒泡排序(Bubble Sort):
-
- 比较相邻的元素,如果顺序错误就交换它们,重复这个过程直到整个数组排序完成。
- 时间复杂度:平均 O(n^2),最坏 O(n^2)。
- 选择排序(Selection Sort):
-
- 从未排序的部分选择最小的元素,与未排序部分的第一个元素交换位置,重复这个过程直到整个数组排序完成。
- 时间复杂度:平均 O(n^2),最坏 O(n^2)。
- 插入排序(Insertion Sort):
-
- 将数组分为已排序和未排序两部分,每次从未排序部分取出一个元素插入到已排序部分的正确位置。
- 时间复杂度:平均 O(n^2),最坏 O(n^2)。
- 归并排序(Merge Sort):
-
- 利用分治法,将数组分成两半,分别排序后再合并。
- 时间复杂度:平均 O(n log n),最坏 O(n log n)。
- 快速排序(Quick Sort):
-
- 选择一个基准元素,将数组分为两部分,左边的元素小于基准,右边的元素大于基准,然后递归地对两部分进行排序。
- 时间复杂度:平均 O(n log n),最坏 O(n^2)。
- 堆排序(Heap Sort):
-
- 构建一个最大堆(或最小堆),不断地将堆顶元素与最后一个元素交换,然后重新调整堆,直到整个数组有序。
- 时间复杂度:平均 O(n log n),最坏 O(n log n)。
- 希尔排序(Shell Sort):
-
- 是插入排序的改进版,通过对数组进行多次分组和插入排序,逐渐减小分组的间隔,直到间隔为1时进行最后一次插入排序。
- 时间复杂度:平均 O(n log n),最坏取决于间隔序列。
- 计数排序(Counting Sort):
-
- 计数排序假设输入的数据是由确定的范围内的整数构成,通过计数每个元素的出现次数,然后进行排序。
- 时间复杂度:O(n + k),其中 k 是非负整数的最大值。
- 桶排序(Bucket Sort):
-
- 将数据分散到有限数量的桶中,对每个桶中的数据进行排序,然后按照桶的顺序将数据合并。
- 时间复杂度:取决于桶的数量和每个桶内的排序算法。