手撕java必备

发布时间:2024年01月19日

刚需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 b
??????????? b = in.nextLine();?????
??????? }

??????? String[] c=b.trim().split(" ");//.trim()可以去掉,以空格切割b为String[] c

??????? int[] 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);
??? }
}

排序算法

排序算法是一类将一组元素按照特定顺序重新排列的算法。以下是一些常见的排序算法:

  1. 冒泡排序(Bubble Sort):
    • 比较相邻的元素,如果顺序错误就交换它们,重复这个过程直到整个数组排序完成。
    • 时间复杂度:平均 O(n^2),最坏 O(n^2)。
  1. 选择排序(Selection Sort):
    • 从未排序的部分选择最小的元素,与未排序部分的第一个元素交换位置,重复这个过程直到整个数组排序完成。
    • 时间复杂度:平均 O(n^2),最坏 O(n^2)。
  1. 插入排序(Insertion Sort):
    • 将数组分为已排序和未排序两部分,每次从未排序部分取出一个元素插入到已排序部分的正确位置。
    • 时间复杂度:平均 O(n^2),最坏 O(n^2)。
  1. 归并排序(Merge Sort):
    • 利用分治法,将数组分成两半,分别排序后再合并。
    • 时间复杂度:平均 O(n log n),最坏 O(n log n)。
  1. 快速排序(Quick Sort):
    • 选择一个基准元素,将数组分为两部分,左边的元素小于基准,右边的元素大于基准,然后递归地对两部分进行排序。
    • 时间复杂度:平均 O(n log n),最坏 O(n^2)。
  1. 堆排序(Heap Sort):
    • 构建一个最大堆(或最小堆),不断地将堆顶元素与最后一个元素交换,然后重新调整堆,直到整个数组有序。
    • 时间复杂度:平均 O(n log n),最坏 O(n log n)。
  1. 希尔排序(Shell Sort):
    • 是插入排序的改进版,通过对数组进行多次分组和插入排序,逐渐减小分组的间隔,直到间隔为1时进行最后一次插入排序。
    • 时间复杂度:平均 O(n log n),最坏取决于间隔序列。
  1. 计数排序(Counting Sort):
    • 计数排序假设输入的数据是由确定的范围内的整数构成,通过计数每个元素的出现次数,然后进行排序。
    • 时间复杂度:O(n + k),其中 k 是非负整数的最大值。
  1. 桶排序(Bucket Sort):
    • 将数据分散到有限数量的桶中,对每个桶中的数据进行排序,然后按照桶的顺序将数据合并。
    • 时间复杂度:取决于桶的数量和每个桶内的排序算法。

文章来源:https://blog.csdn.net/qq_53631388/article/details/135686858
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。