JAVA机试练习(2023华为od练手题PDF)

目录

一、字符串操作

二、排序

三、栈

四、排列组合

五、双指针

六、深度搜索

七、二叉树

八、其他


1.HJ5进制转换,16变10

     JAVA实现16进制转10进制_java十六进制转十进制_奥特曼下象棋的博客-CSDN博客

2.HJ3去除重复数

 明明的随机数【Java】_小明的随机数_小明丶的博客-CSDN博客

3.HJ10 字符个数统计

【java算法】HJ10 字符个数统计_lucky__cc的博客-CSDN博客

4.NC61两数之和

牛客 NC61 两数之和(Java 哈希表) - Jolyne123 - 博客园 (cnblogs.com)

5.NC68跳台阶

Nc68-跳台阶_无尽的沉默的博客-CSDN博客

一、字符串操作

1.HJ17坐标移动

import java.util.*;
import java.io.*;
 
public class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] in = bf.readLine().split(";");
        int x = 0;
        int y = 0;
        for(String s : in){
            // 不满足题目给定坐标规则
            if(!s.matches("[WASD][0-9]{1,2}")){
                continue;
            }
            int val = Integer.valueOf(s.substring(1));
            switch(s.charAt(0)){
                case 'W':
                    y += val;
                    break;
                case 'S':
                    y -= val;
                    break;
                case 'A':
                    x -= val;
                    break;
                case 'D':
                    x += val;
                    break;
            }
        }
        System.out.println(x+","+y);
    }
}

2.HJ20.密码验证合格程序

import java.util.*;
import java.util.regex.*;
public class Main{
    public static void main(String[] arg){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str = sc.next();
            if(str.length() <= 8){
                System.out.println("NG");
                continue;
            }
            if(getMatch(str)){
                System.out.println("NG");
                continue;
            }
            if(getString(str, 0, 3)){
                System.out.println("NG");
                continue;
            }
            System.out.println("OK");
        }
    }
    // 校验是否有重复子串
    private static boolean getString(String str, int l, int r) {
        if (r >= str.length()) {
            return false;
        }
        if (str.substring(r).contains(str.substring(l, r))) {
            return true;
        } else {
            return getString(str,l+1,r+1);
        }
    }
    // 检查是否满足正则
    private static boolean getMatch(String str){
        int count = 0;
        Pattern p1 = Pattern.compile("[A-Z]");
        if(p1.matcher(str).find()){
            count++;
        }
        Pattern p2 = Pattern.compile("[a-z]");
        if(p2.matcher(str).find()){
            count++;
        }
        Pattern p3 = Pattern.compile("[0-9]");
        if(p3.matcher(str).find()){
            count++;
        }
        Pattern p4 = Pattern.compile("[^a-zA-Z0-9]");
        if(p4.matcher(str).find()){
            count++;
        }
        if(count >= 3){
            return false;
        }else{
            return true;
        }
    }
}

3.*HJ23.删除字符串中出现次数最少的字符

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    while (sc.hasNext()) {
        String s = sc.nextLine();
        char[] c = s.toCharArray();
        //统计每个字母的数量
        HashMap<Character, Integer> map = new HashMap<>();
        for (char aChar : c) {
               map.put(aChar, (map.getOrDefault(aChar, 0) + 1));
        }
        //找到数量最少的字符数量
        Collection<Integer> values = map.values();
        Integer min = Collections.min(values);
        //用空字符串替换该字母
        for (Character character : map.keySet()) {
            if (map.get(character) == min){
                s = s.replaceAll(String.valueOf(character), "");
            }
        }
        System.out.println(s);
    }
  }
}

4.)*HJ33.整数与IP地址间的转换

import java.util.*;


public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in); 
       while (sc.hasNext()) {
        String str = sc.next(); 
        // ipv4 -> int
        if (str.contains(".")) {
            String[] fields = str.split("\\.");
            long result = 0;
            for (int i = 0; i < 4; i++) {
                result = result * 256 + Integer.parseInt(fields[i]);
            }
            System.out.println(result);
        }
        // int -> ipv4
        else {
            long ipv4 = Long.parseLong(str);
            String result = "";
            for (int i = 0; i < 4; i++) {
                result = ipv4 % 256 + "." + result;
                ipv4 /= 256;
            }
            System.out.println(result.substring(0, result.length() - 1));
        }
    }    
    }
}

5.HJ101.输入整型数组和排序标识

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) { // 注意 while 处理多个 case
            int n = in.nextInt();//接收数组长度
            int[] a = new int[n];//创建数组
            for (int i = 0; i < n; i++) {//数组填入
                a[i] = in.nextInt();
            }
            int flag = in.nextInt();//接收排序标识
            Arrays.sort(a);//数组排序
            if(flag==0){
               for(int i =0; i < a.length; i++) 
                    System.out.print(a[i] + " ");
            }else{
                for(int i=a.length-1;i>=0;i--)
                    System.out.print(a[i]+" ");
            }
        }
    }
}

6.*HJ106.字符串逆序

import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            StringBuilder res = new StringBuilder(str);
            System.out.println(res.reverse().toString());
        }
    }
}

7.leetcode 1839 最长子字符串

  LeetCode——1839. 所有元音按顺序排布的最长子字符串(Longest Substring Of All Vowels in Order)[中等]——分析及代码(Java)_江南土豆的博客-CSDN博客

解法3贪心算法效率更优。

8.HJ46 截取字符串

System.out.println(s.substring(0,N));

二、排序

1.)HJ8.合并表记录

import java.util.*; 
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TreeMap<Integer,Integer> map=new TreeMap<>();
        while(sc.hasNextInt()){
            int n=sc.nextInt();
            for(int i=0;i<n;i++){
                int k=sc.nextInt();
                int v=sc.nextInt();
                map.put(k,map.getOrDefault(k,0)+v);
            }
            for(Integer i:map.keySet()){
                System.out.println(i+" "+map.get(i));
            }
        }
    }
}

2.*HJ14.字符串排序

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n=sc.nextInt();
        String a[]=new String[n];
        for(int i=0;i<n;i++){
            a[i]=sc.next();
        }
        Arrays.sort(a);
        for(String str:a){
            System.out.println(str);
        }        
    }
}

3.HJ27.查找兄弟单词

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String s[]=sc.nextLine().split(" ");
            Integer n=Integer.parseInt(s[0]);
            String find=s[s.length-2];
            Integer k=Integer.parseInt(s[s.length-1]);
            List<String> list=new ArrayList<>();

            for(int i=1;i<=n;i++){
                if(isBro(find,s[i])){
                    list.add(s[i]);
                }
            }
            int size=list.size();
            System.out.println(size);
            if(size>=k){
                Collections.sort(list);
                System.out.println(list.get(k-1));
            }
        }
    }
    public static boolean isBro(String x,String y){
        if (x.length()!=y.length()||y.equals(x)){
            return false;
        }
        char[] s = x.toCharArray();
        char[] j= y.toCharArray();
        Arrays.sort(s);
        Arrays.sort(j);
        return new String(s).equals(new String(j));
    }
}

4.*NC37.合并区间

import java.util.*;

public class Solution {
    public ArrayList<Interval> merge(ArrayList<Interval> intervals){
        ArrayList<Interval> res=new ArrayList<>();
        //
        if(intervals.size()==0)
        return res;
        //重载比较,按照区间首排序
        Collections.sort(intervals,new Comparator<Interval>(){
            public int compare(Interval o1, Interval o2){
                if(o1.start!=o2.start)
                   return o1.start-o2.start;
                else
                     return o1.end-o2.end;
            }
        });
        //放入第一个区间
        res.add(intervals.get(0));
        int count=0;
        //遍历后续区间,查看是否与末尾有重叠
        for(int i = 1; i < intervals.size(); i++){
            Interval o1 = intervals.get(i);
            Interval origin = res.get(count);
            if(o1.start > origin.end){
                res.add(o1);
                count++;
            }else{
                res.remove(count);
                Interval s = new Interval(origin.start, o1.end);
                if(o1.end < origin.end)
                    s.end = origin.end;
                res.add(s);   
            }
        }
        return res;
    }

}

具体做法:

step 1:既然要求重叠后的区间按照起点位置升序排列,我们就将所有区间按照起点位置先进行排序。使用sort函数进行排序,重载比较方式为比较interval结构的start变量。
step 2:排序后的第一个区间一定是起点值最小的区间,我们将其计入返回数组res,然后遍历后续区间。
step 3:后续遍历过程中,如果遇到起点值小于res中最后一个区间的末尾值的情况,那一定是重叠,取二者最大末尾值更新res中最后一个区间即可。
step 4:如果遇到起点值大于res中最后一个区间的末尾值的情况,那一定没有重叠,后续也不会有这个末尾的重叠区间了,因为后面的起点只会更大,因此可以将它加入res。

复杂度分析:

  • 时间复杂度:O(nlog2n),排序的复杂度为O(nlog2n),后续遍历所有区间的复杂度为O(n),属于低次幂,忽略
  • 空间复杂度:O(1),res为返回必要空间,没有使用额外辅助空间

5.*HJ68.成绩排序

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        HashMap<Integer,String> map = new HashMap<>();
        // 注意 hasNext 和 hasNextLine 的区别
        while (sc.hasNextLine()) {
            int n=Integer.parseInt(sc.nextLine());
            int flag=Integer.parseInt(sc.nextLine());//1 0
            int[][] grades=new int[n][2];//
            for(int i=0;i<n;i++){
                String[] NameAndScore=sc.nextLine().split("\\s+");
                grades[i][0]=i;
                grades[i][1] = Integer.parseInt(NameAndScore[1]);
                map.put(i,NameAndScore[0]);
            }
            Arrays.sort(grades,(o1,o2)->{
                if(flag==0){
                    return o2[1]-o1[1];
                }else{
                    return o1[1]-o2[1];
                }
            });
            for(int i=0;i<n;i++) 
               System.out.println(map.get(grades[i][0])+" "+grades[i][1]);
        }
    }
}

Java使用lambda自定义Arrays.sort排序规则说明_java_脚本之家 (jb51.net)

三、栈

1.NC52.括号序列

import java.util.*;

public class Solution {
    public boolean isValid (String s) {
        //辅助栈
        Stack<Character> st=new Stack<>();
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='(')
                st.push(')');
            else if(s.charAt(i) == '[')
                st.push(']');
            else if(s.charAt(i) == '{')
                st.push('}');
            //必须有左括号的情况下才能遇到右括号
            else if(st.isEmpty() || st.pop() != s.charAt(i))
            return false;
        }
        //栈中是否还有元素
        return st.isEmpty();
    }
}

复杂度分析:

时间复杂度:O(n),其中n为字符串长度,遍历整个字符串
空间复杂度:O(n),最坏情况下栈空间中记录整个字符串长度的右括号

2.*leetcode 1614.括号的最大嵌套深度

方法一:遍历
对于括号计算类题目,我们往往可以用栈来思考。

遍历字符串 s,如果遇到了一个左括号,那么就将其入栈;如果遇到了一个右括号,那么就弹出栈顶的左括号,与该右括号匹配。这一过程中的栈的大小的最大值,即为 s 的嵌套深度。

代码实现时,由于我们只需要考虑栈的大小,我们可以用一个变量size 表示栈的大小,当遇到左括号时就将其加一,遇到右括号时就将其减一,从而表示栈中元素的变化。这一过程中 size 的最大值即为 s 的嵌套深度。

class Solution {
    public int maxDepth(String s) {
        int ans = 0, size = 0;
        for (int i = 0; i < s.length(); ++i) {
            char ch = s.charAt(i);
            if (ch == '(') {
                ++size;
                ans = Math.max(ans, size);
            } else if (ch == ')') {
                --size;
            }
        }
        return ans;
    }
}

复杂度分析

时间复杂度:O(n),其中 n 是字符串 s 的长度。

空间复杂度:O(1)。我们只需要常数空间来存放若干变量。

四、排列组合

1.*leetcode 面试题08.08.有重复字符串的排列组合

回溯全排列题解。

力扣

2.leetcode 77.组合

方法一:递归实现组合型枚举

class Solution {
    List<Integer> temp = new ArrayList<Integer>();
    List<List<Integer>> ans = new ArrayList<List<Integer>>();

    public List<List<Integer>> combine(int n, int k) {
        dfs(1, n, k);
        return ans;
    }

    public void dfs(int cur, int n, int k) {
        // 剪枝:temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 temp
        if (temp.size() + (n - cur + 1) < k) {
            return;
        }
        // 记录合法的答案
        if (temp.size() == k) {
            ans.add(new ArrayList<Integer>(temp));
            return;
        }
        // 考虑选择当前位置
        temp.add(cur);
        dfs(cur + 1, n, k);
        temp.remove(temp.size() - 1);
        // 考虑不选择当前位置
        dfs(cur + 1, n, k);
    }
}

执行用时:1 ms, 在所有 Java 提交中击败了99.97%的用户
内存消耗:42.8 MB, 在所有 Java 提交中击败了48.55%的用户

复杂度分析

时间复杂度:O(( kn)×k),分析见「思路」部分。
空间复杂度:O(n + k) =O(n),即递归使用栈空间的空间代价和临时数组 temp 的空间代价。

五、双指针

1.*leetcode 674.最长连续递增序列

画解算法解题思路
标签:遍历
过程:
count 为当前元素峰值,ans为最大峰值
初始化 count = 1
从 0 位置开始遍历,遍历时根据前后元素状态判断是否递增,递增则 count++,递减则 count=1
如果 count>ans,则更新 ans
直到循环结束
时间复杂度:O(N)

public int findLengthOfLCIS(int[] nums) {
        if(nums.length <= 1)
            return nums.length;
        int ans = 1;
        int count = 1;
        for(int i=0;i<nums.length-1;i++) {
            if(nums[i+1] > nums[i]) {
                count++;
            } else {  
                count = 1;
            }
            ans = count > ans ? count : ans;
        }
        return ans;
    }

2.NC17.最长回文子串     中心扩展法(推荐使用)  贪心

最长回文子串_牛客题霸_牛客网

因为最后一次不满足条件退出循环时,在上一次循环中begin和end的差值已经被扩大了2了,所以实际上是end-begin+1-2,最后是end-begin-1

3.NC28.最小覆盖子串        较难     滑动窗口。。

题解 | #最小覆盖子串#_牛客博客

六、深度搜索

1.HJ41.称砝码

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) { // 注意 while 处理多个 case
            HashSet<Integer> set = new HashSet<>();
            set.add(0);
            int N = sc.nextInt();
            int[] w = new int[N];
            int[] n = new int[N];
            for (int i = 0; i < N; i++) {
                w[i] = sc.nextInt();//砝码的重量
            }
            for (int i = 0; i < N; i++) {
                n[i] = sc.nextInt();//砝码个数
            }
            for (int i = 0; i < N; i++) {//遍历砝码
                ArrayList<Integer> list=new ArrayList<>(set);//取当前所有的结果
                for(int j=1;j<=n[i];j++){//遍历个数
                    for(int k=0;k<list.size();k++){
                        set.add(list.get(k)+w[i]*j);
                    }
                }

            }
            System.out.println(set.size());
        }
    }
}

七、二叉树

1.*leetcode 剑指offer 32 — II.从上到下打印二叉树 II

class Solution {

    public List<List<Integer>> levelOrder(TreeNode root) {

        Queue<TreeNode> queue = new LinkedList<>();

        List<List<Integer>> ans = new ArrayList<>();

        if(root != null) queue.add(root);

        while(!queue.isEmpty()) {

            List<Integer> tmp = new ArrayList<>();

            for(int i = queue.size(); i > 0; i--) {

                TreeNode node = queue.poll();

                tmp.add(node.val);

                if(node.left != null) queue.add(node.left);

                if(node.right != null) queue.add(node.right);

            }

            ans.add(tmp);

        }

        return ans;

    }

}

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:41.7 MB, 在所有 Java 提交中击败了30.17%的用户

2.leetcode 剑指offer 32 — III.从上到下打印二叉树 III

   参考大佬题解,思路步骤清晰!!!

力扣

八、其他

1.*HJ108.求最小公倍数

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int a = in.nextInt();
            int b = in.nextInt();
            int lcm = a * b / gcd(a, b);
            System.out.println(lcm);
        }
    }
    public static int gcd(int a, int b) {
        if (b == 0)return a;
        return gcd(b, a % b);
    }
}

2.*HJ28.素数伴侣  困难

import java.util.*;
public class Main {

    //这里包含了判断素数的方法
    //小技巧!!!素数不是偶数,那么和是素数的话就是奇数+偶数
    //那么可以分成两堆,一堆偶数,一堆奇数
    //匈牙利算法,先到先得 能让就让
    //有机会上,没机会创造机会也要上
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner scan = new Scanner(System.in);
        while(scan.hasNext()){
            int n = scan.nextInt();
            int[] tempArray = new int[n];
            for(int i = 0; i < n; i++){
                tempArray[i] = scan.nextInt();
            }
            ArrayList<Integer> evens = new ArrayList<Integer>();
            ArrayList<Integer> odds = new ArrayList<Integer>();
            for(int i = 0; i < n; i++) {
                if((tempArray[i] & 1) != 1) {
                    evens.add(tempArray[i]);
                }else {
                    odds.add(tempArray[i]);
                }
            }
            //下面开始才是重头戏
            //用于标记那个奇数匹配了偶数,直接记录奇数的值,而不是奇数在奇数数组中的下标
            int[] evensMatch =new int[evens.size()];
            int result = 0;
            //遍历奇数去匹配偶数
            for(int i = 0; i < odds.size(); i++) {
                //每一步重新创建,也就是相当于清空
                //used数组用于标记某个某数位置是否
                int[] used = new int[evens.size()];
                //这里采用了匈牙利算法,先到先得
                if(find(odds.get(i), evens, used, evensMatch)) {
                    result++;
                }
            }
            System.out.println(result);
        }
    }

    public static boolean isPrime(int num) {
        for(int i = 2; i * i <= num; i++) {
            if(num % i == 0) {
                return false;
            }
            if(num == 1) {
                return false;
            }
        }
        return true;
    }

    public static boolean find(int x, ArrayList<Integer> evens,int[] used, int[] evensMatch) {
        //遍历偶数
        //去检查当前传入的奇数能否与偶数哪些数匹配
        for(int i = 0; i < evens.size(); i++) {
            //如果当前偶数与传入的奇数匹配,并且当前偶数位还没有匹配过奇数
            if(isPrime(x + evens.get(i)) && used[i] == 0) {
                //设置当前偶数位匹配为true,也就是 1
                used[i] = 1;
                //如果第i个偶数没有伴侣
                //或者第i个偶数原来有伴侣,并且该伴侣能够重新找到伴侣的话(这里有递归调用)
                //则奇数x可以设置为第i个偶数的伴侣
                //这里采用了匈牙利算法,能让则让
                if(evensMatch[i] == 0 || find(evensMatch[i], evens, used, evensMatch)) {
                    evensMatch[i] = x;
                    return true;
                }
            }
        }
        //遍历完偶数都没有可以与传入奇数做伴侣的,该奇数只能孤独终老了
        return false;
    }

}

n3,n

3.*HJ60.查找组成一个偶数最接近的两个素数

方法二:穷举优化

解题思路:

采取从中间向两边枚举的方式,这样贪心的控制住两素数之差距离最小的这个限制

算法流程:

对于每个数字,从最接近的两个中位数开始处理判断是否素数
如果两个组成偶数的数字都是素数,因为是从最接近的两个数开始枚举,因此一旦都是素数则输出并返回,得到结果

import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
        	int num = scanner.nextInt();
        	solution(num);
        }
    }

    private static void solution(int num) {
        //如num=10, 遍历:5,6,7,8
        // 从最接近的两个中位数开始处理判断
        for(int i = num / 2; i < num - 1; i++) {
            if(isPrime(i) && isPrime(num - i)) {
                System.out.println((num - i) + "\n" + i);
                return;
            }
        }
    }
    // 判断是否素数
    private static boolean isPrime(int num) {
        for(int i = 2; i <= Math.sqrt(num); i++) {
            if(num % i == 0) {
                return false;
            }
        } 
        return true;
    }
}

复杂度分析:时间复杂度:NsqrtN  ,外循环最多遍历 N/2 次,内循环每个数最多sqrtN

空间复杂度:O(1),只用到常数级别的空间开销

4.*leetcode 994.腐烂的橘子  BFS   层序遍历,可求最短路径

力扣

5.leetcode 204.计数质数

方法二:埃氏筛
枚举没有考虑到数与数的关联性,因此难以再继续优化时间复杂度。接下来我们介绍一个常见的算法,该算法由希腊数学家厄拉多塞(\rm EratosthenesEratosthenes)提出,称为厄拉多塞筛法,简称埃氏筛。

我们考虑这样一个事实:如果 xx 是质数,那么大于 xx 的 xx 的倍数 2x,3x,\ldots2x,3x,… 一定不是质数,因此我们可以从这里入手。

我们设 \textit{isPrime}[i]isPrime[i] 表示数 ii 是不是质数,如果是质数则为 11,否则为 00。从小到大遍历每个数,如果这个数为质数,则将其所有的倍数都标记为合数(除了该质数本身),即 00,这样在运行结束的时候我们即能知道质数的个数。

这种方法的正确性是比较显然的:这种方法显然不会将质数标记成合数;另一方面,当从小到大遍历到数 xx 时,倘若它是合数,则它一定是某个小于 xx 的质数 yy 的整数倍,故根据此方法的步骤,我们在遍历到 yy 时,就一定会在此时将 xx 标记为 \textit{isPrime}[x]=0isPrime[x]=0。因此,这种方法也不会将合数标记为质数。

当然这里还可以继续优化,对于一个质数 xx,如果按上文说的我们从 2x2x 开始标记其实是冗余的,应该直接从 x\cdot xx⋅x 开始标记,因为 2x,3x,\ldots2x,3x,… 这些数一定在 xx 之前就被其他数的倍数标记过了,例如 22 的所有倍数,33 的所有倍数等。

class Solution {
    public int countPrimes(int n) {
        int[] isPrime = new int[n];
        Arrays.fill(isPrime, 1);
        int ans = 0;
        for (int i = 2; i < n; ++i) {
            if (isPrime[i] == 1) {
                ans += 1;
                if ((long) i * i < n) {
                    for (int j = i * i; j < n; j += i) {
                        isPrime[j] = 0;
                    }
                }
            }
        }
        return ans;
    }
}

力扣官方题解多角度多语言,还有延伸面试外的优选方法线性函数。。。

6.HJ25. 数据分类处理  较难

数据分类处理_牛客题霸_牛客网

7.HJ29 字符串加解密

超时。。。。。。用映射。。还要加其他不用处理的字符


//tips:大小写转换不用查ASCII码表,通过字符加减就能实现
//有大佬说数字转换可以通过加一再除以十取余数的方式实现,这样不用单独考虑9,方便多了!
    
    //解密函数
    private static String decode(String password) {
        char[] t = password.toCharArray();
        //注意减法要再加一个26或10,才可以正常循环起来
        for (int i = 0; i < t.length; i++) {
            if (t[i] >= 'a' && t[i] <= 'z') {
                t[i] = (char) ((t[i] - 'a' - 1 + 26) % 26 + 'A');
            } else if (t[i] >= 'A' && t[i] <= 'Z') {
                t[i] = (char) ((t[i] - 'A' - 1 + 26) % 26 + 'a');
            } else if (t[i] >= '0' && t[i] <= '9') {
                t[i] = (char) ((t[i] - '0' - 1 + 10) % 10 + '0');
            }
        }
        return String.valueOf(t);
    }

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);

       

        while (in.hasNext()) {

            String a = in.nextLine();

            String b = in.nextLine();

            System.out.println(encrypt(a));

            System.out.println(decrypt(b));

        }

    }

   

    private static char[] mletter = "abcdefghijklmnopqrstuvwxyz".toCharArray();

    private static char[] cletter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();

    private static char[] number = "0123456789".toCharArray();

   

    private static String encrypt(String input) {

        char[] arr = input.toCharArray();

        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < arr.length; i++) {

            int index = (int)arr[i];

            if (arr[i] >= 'a' && arr[i] <= 'z') {

                builder.append(cletter[(index - 97 + 1) % 26]); // 字母a的int值是97,我们这里减成0后+1然后对26(a-z=26个字母)取模,再去大写数组里找对应下标就是了

            } else if (arr[i] >= 'A' && arr[i] <= 'Z') {

                builder.append(mletter[(index - 65 + 1) % 26]);

            } else if (arr[i] >= '0' && arr[i] <= '9') {

                builder.append(number[(index - 48 + 1) % 10]);

            } else {

                builder.append(arr[i]);

            }

        }

        return builder.toString();

    }

   

    private static String decrypt(String input) {

        char[] arr = input.toCharArray();

        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < arr.length; i++) {

            int index = (int)arr[i];

            if (arr[i] >= 'a' && arr[i] <= 'z') {

                builder.append(cletter[(index - 97 + 26 - 1) % 26]); // 字母a的int值是97,为了防止负数出现,我们加26后再取模.PS:取模就跟拨时钟一样,12个钟多拨一圈会回到原点;)

            } else if (arr[i] >= 'A' && arr[i] <= 'Z') {

                builder.append(mletter[(index - 65 + 26 - 1) % 26]);

            } else if (arr[i] >= '0' && arr[i] <= '9') {

                builder.append(number[(index - 48 + 10 - 1) % 10]);

            } else {

                builder.append(arr[i]);

            }

        }

        return builder.toString();

    }

}

8.剑指 Offer 61. 扑克牌中的顺子

多种思路

力扣

class Solution {
    public boolean isStraight(int[] nums) {
        int joker = 0;
        Arrays.sort(nums); // 数组排序
        for(int i = 0; i < 4; i++) {
            if(nums[i] == 0) joker++; // 统计大小王数量
            else if(nums[i] == nums[i + 1]) return false; // 若有重复,提前返回 false
        }
        return nums[4] - nums[joker] < 5; // 最大牌 - 最小牌 < 5 则可构成顺子
    }
}

9.HJ43 迷宫问题     BFS

  • offer() 是往队列中添加一个元素,若队列已满而仍往队列中添加,则会返回false
  • poll() 是删除队列中的第一个元素,在对空队列进行操作时,返回null
  • peek() 是输出队列的第一个元素,队列为空时,返回null

题解 | #迷宫问题#_牛客博客

10.leetcode 322. 零钱兑换 ,也可搜索 动态规划相关题型 (技术面试高频考点)

动规力扣

memo[i] 有两种实现的方式,去两者的最小值

包含当前的 coins[i]coins[i],那么剩余钱就是 i-coins[i]i−coins[i],这种操作要兑换的硬币数是 memo[i-coins[j]] + 1memo[i−coins[j]]+1

不包含,要兑换的硬币数是 memo[i]memo[i]

class Solution {
    public int coinChange(int[] coins, int amount) {
        // 自底向上的动态规划
        if(coins.length == 0){
            return -1;
        }

        // memo[n]的值: 表示的凑成总金额为n所需的最少的硬币个数
        int[] memo = new int[amount+1];
        // 给memo赋初值,最多的硬币数就是全部使用面值1的硬币进行换
        // amount + 1 是不可能达到的换取数量,于是使用其进行填充
        Arrays.fill(memo,amount+1);
        memo[0] = 0;
        for(int i = 1; i <= amount;i++){
            for(int j = 0;j < coins.length;j++){
                if(i - coins[j] >= 0){
                    // memo[i]有两种实现的方式,
                    // 一种是包含当前的coins[i],那么剩余钱就是 i-coins[i],这种操作要兑换的硬币数是 memo[i-coins[j]] + 1
                    // 另一种就是不包含,要兑换的硬币数是memo[i]
                    memo[i] = Math.min(memo[i],memo[i-coins[j]] + 1);
                }
            }
        }

        return memo[amount] == (amount+1) ? -1 : memo[amount];
    }
}

11.岛屿问题 leetcode 200 (技术面试高频考点)

我们所熟悉的 DFS(深度优先搜索)问题通常是在树或者图结构上进行的。而我们今天要讨论的 DFS 问题,是在一种「网格」结构中进行的。岛屿问题是这类网格 DFS 问题的典型代表。网格结构要比二叉树结构稍微复杂一些,它其实是一种简化版的图结构

力扣

12.火锅问题

【华为机试】【贪心】【Java】导师请吃火锅_编程题贪心的商人_Twish的博客-CSDNguanfa

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值