博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

LeetCode刷题

Posted on 2020-01-26 17:48  心默默言  阅读(467)  评论(0编辑  收藏  举报

1.字符串最后一个单词的长度

计算字符串最后一个单词的长度,单词以空格隔开。

输入描述:

一行字符串,非空,长度小于5000。

输出描述:

整数N,最后一个单词的长度。

示例1

输入

hello world

输出

5
import java.util.Scanner;

/**
 * 计算字符串最后一个单词的长度,单词以空格隔开。
 *
 */
public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String s = scanner.nextLine();
            String[] words = s.split(" ");
            System.out.println(words[words.length-1].length());
        }
    }
}

2.计算字符个数

写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。

输入描述:

第一行输入一个有字母和数字以及空格组成的字符串,第二行输入一个字符。

输出描述:

输出输入字符串中含有该字符的个数。

示例1

输入

ABCDEF
A

输出

1
import java.util.Scanner;

/**
 * 接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。
 *
 */
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s = input.next().toUpperCase();
        char c = input.next().toUpperCase().charAt(0);
        int count = getNum(s, c);
        System.out.println(count);
    }

    /*public static int getNum(String s, char c) {
        char[] arr = s.toCharArray();
        int count = 0;
        for (char i : arr) {
            if (i == c)
                count++;
        }
        return count;
    }*/

    public static int getNum(String s, char c) {
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (c == s.charAt(i))
                count++;
        }
        return count;
    }
}

3.去重和排序

对一组数据完成去重与排序的工作,注意第一个数字为数据的个数。

import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

/**
 * 对一组数据完成去重与排序的工作
 * 
 */
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            int num = input.nextInt();
            Set<Integer> set = new TreeSet<>();
            for (int i = 0; i < num; i++) {
                set.add(input.nextInt());
            }

            for (Integer i : set) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }

}

4.字符串分割与补零

•连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组; 

•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。

输入描述:

连续输入字符串(输入2次,每个字符串长度小于100)

输出描述:

输出到长度为8的新字符串数组

示例1

输入

abc
123456789

输出

abc00000
12345678
90000000
import java.util.Scanner;

/**
 * •连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组;
 * •长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
 */
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNextLine()) {
            String s = input.nextLine();
            splitString(s);
            System.out.println();
        }
    }

    public static void splitString(String s) {
        while (s.length() >= 8) {
            System.out.print(s.substring(0, 8)+" ");
            s = s.substring(8);
        }
        
        if (s.length() < 8 && s.length() > 0) {
            s = s + "0000000";
            System.out.print(s.substring(0, 8));
        }
    }
}

5.十六进制转换为十进制

写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。(多组同时输入 )

输入描述:

输入一个十六进制的数值字符串。

输出描述:

输出该数值的十进制字符串。

示例1

输入

0xA

输出

10
import java.util.Scanner;


public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String s = input.nextLine();
        /*    char[] arr = s.toCharArray();
            int result = 0;
            int index = 0;
            for (int i = arr.length - 1; i > 1; i--) {
                int num = conversion(arr[i]);
                result += num * Math.pow(16, index++);
            }
            System.out.println(result);*/
            
            System.out.println(conversion(s.substring(2)));
        }
        input.close();
    }public static int conversion(String s) {
        int n = 0;
        int count = 0;
        int temp = 0;
        char ch;

        while (count < s.length()) {
            ch = s.charAt(s.length() - count - 1);
            if (ch >= '0' && ch <= '9') {
                temp = ch - '0';
            } else if (ch >= 'A' && ch <= 'Z') {
                temp = ch - 'A' + 10;
            } else if (ch >= 'a' && ch <= 'z') {
                temp = ch - 'a' + 10;
            } else {
                break;
            }
            n += temp * Math.pow(16, count);
            count++;
        }

        return n;
    }
}

6.质数因子

功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(如180的质因子为2 2 3 3 5 )

最后一个数后面也要有空格

输入描述:

输入一个long型整数

输出描述:

按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。

示例1

输入

180

输出

2 2 3 3 5

import java.util.Scanner;

/**
 * 功能:输入一个正整数,按照从小到大的顺序输出它的所有质数的因子(如180的质数因子为2 2 3 3 5 )最后一个数后面也要有空格
 */
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Long number = input.nextLong();
        if (number < 2) {
            input.close();
            return;
        }
        isPrimeFactors(number);
        input.close();

    }

    public static void isPrimeFactors(Long number) {
        while (number != 1) {
            for (int i = 2; i <= number; i++) {
                if (number % i == 0) {
                    number = number / i;
                    System.out.print(i + " ");
                    break;
                }
            }
        }
    }
}

7.四舍五入

写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。

输入描述:

输入一个正浮点数值

输出描述:

输出该数值的近似整数值

示例1

输入

5.5

输出

6
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        double number = input.nextDouble();
        int res = round(number);
        System.out.println(res);
        input.close();
    }

    public static int round(double number) {
        int res = (int) number;
        return (number - res) >= 0.5 ? res + 1 : res;
    }
}

8.对表索引相同的记录进行合并

数据表记录包含表索引和数值(int范围的整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。

输入描述:

先输入键值对的个数
然后输入成对的index和value值,以空格隔开

输出描述:

输出合并后的键值对(多行)

示例1

输入

4
0 1
0 2
1 2
3 4

输出

0 3
1 2
3 4
import java.util.Scanner;
import java.util.TreeMap;


public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int num = Integer.parseInt(input.nextLine());

        TreeMap<Integer, Integer> map = new TreeMap<>();
        for (int i = 0; i < num; i++) {
            String s = input.nextLine();
            getResult(s, map);
        }

        for (Integer key : map.keySet()) {
            System.out.println(key + " " + map.get(key));
        }

    }

    public static void getResult(String s, TreeMap<Integer, Integer> map) {
        String[] arr = s.split(" ");
        int key = Integer.parseInt(arr[0]);
        int value = Integer.parseInt(arr[1]);
        if (map.containsKey(key)) {
            value += map.get(key);
            map.put(key, value);
        } else {
            map.put(key, value);
        }
    }

}

 

9.提取不重复的整数

输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。

输入描述:

输入一个int型整数

输出描述:

按照从右向左的阅读顺序,返回一个不含重复数字的新的整数

示例1

输入

9876673

输出

37689

import java.util.LinkedHashSet;
import java.util.Scanner;

public class T09提取不重复的整数 {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        LinkedHashSet<Character> set = new LinkedHashSet<>();
        for (int i = s.length() - 1; i >= 0; i--) {
            char ch = s.charAt(i);
            set.add(ch);
        }
        for (Character ch : set) {
            System.out.print(ch);
        }
        input.close();
    }

}

 

10.统计字符个数

编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127),换行表示结束符,不算在字符里。不在范围内的不作统计。

输入描述:

输入N个字符,字符在ACSII码范围内。

输出描述:

输出范围在(0~127)字符的个数。

示例1

输入

abc

输出

3
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        int count = 0;
        int[] arr = new int[128];
        for (int i = 0; i < s.length(); i++) {
            if (arr[s.charAt(i)] == 0) {
                arr[s.charAt(i)]++;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] != 0) {
                count++;
            }
        }
        System.out.println(count);
    }

}

11.按照字典的顺序排列字符串

给定n个字符串,请对n个字符串按照字典序排列。

输入描述:

输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。

输出描述:

数据输出n行,输出结果为按照字典序排列的字符串。
示例1

输入

9
cap
to
cat
card
two
too
up
boat
boot

输出

boat
boot
cap
card
cat
to
too
two
up

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int num = Integer.parseInt(input.nextLine());
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            String s = input.nextLine();
            list.add(s);
        }
        Collections.sort(list);
        for (String s : list) {
            System.out.println(s);
        }
        input.close();
    }

}

12.密码验证合格程序

密码要求:

1.长度超过8位

2.包括大小写字母.数字.其它符号,以上四种至少三种

3.不能有相同长度超2的子串重复

说明:长度超过2的子串

输入描述:

一组或多组长度超过2的子符串。每组占一行

输出描述:

如果符合要求输出:OK,否则输出NG

示例1

输入

021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000

输出

OK
NG
NG
OK
import java.util.Scanner;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String str = input.nextLine();
            String res = isPassword(str);
            System.out.println(res);
        }

    }

    public static String isPassword(String str) {
        //1.判断长度
        if (str == null || str.length() < 9) {
            return "NG";
        }

        int count = 0;
        //2.判断是否含有三种以上字符
        /*Pattern p1 = Pattern.compile("[a-z]");
        Matcher m1 = p1.matcher(str);
        if (m1.find())
            count++;
        Pattern p2 = Pattern.compile("[A-Z]");
        Matcher m2 = p2.matcher(str);
        if (m2.find())
            count++;
        Pattern p3 = Pattern.compile("[0-9]");
        Matcher m3 = p3.matcher(str);
        if (m3.find())
            count++;
        
        Pattern p4 = Pattern.compile("[^a-zA-Z0-9]");
        Matcher m4 = p4.matcher(str);
        if (m4.find())
            count++;*/
        if (Pattern.matches(".*[a-z]+.*", str)) //+表达式至少出现1次,相当于 {1,}
            count++;
        if (Pattern.matches(".*[A-Z]+.*", str)) //*表达式至少出现0次,表达式不出现或出现任意次,相当于 {0,}
            count++;
        if (Pattern.matches(".*[0-9]+.*", str)) //.小数点可以匹配任意一个字符(除了换行符)
            count++;
        if (Pattern.matches(".*[^a-zA-Z0-9]+.*", str))
            count++;

        if (count < 3) {
            return "NG";

        } else {
            return isHasSubString(str);
        }
    }

    private static String isHasSubString(String str) {
        for (int i = 0; i < str.length() - 3; i++) {
            String str1 = str.substring(i, i + 3);
            String str2 = str.substring(i + 3);
            if (str2.contains(str1))
                return "NG";
        }
        return "OK";
    }
}

13.密码转换

大家都知道手机上的字母: 1--1, abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9, 0--0,就这么简单,渊子把密码中出现的小写字母都变成对应的数字,数字和其他的符号都不做变换,

声明:密码中没有空格,而密码中出现的大写字母则变成小写之后往后移一位,如:X,先变成小写,再往后移一位,不就是y了嘛,简单吧。记住,z往后移是a哦。

输入描述:

输入包括多个测试数据。输入是一个明文,密码长度不超过100个字符,输入直到文件结尾

输出描述:

输出渊子真正的密文

示例1

输入

YUANzhi1987

输出

zvbo9441987
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String str = input.nextLine();
            char[] arr = str.toCharArray();
            for (int i = 0; i < arr.length; i++) {
                char num = arr[i];
                if (num >= '0' && num <= '9') {
                    continue;
                } else if ("abc".contains(num + "")) {
                    arr[i] = '2';
                } else if ("def".contains(num + "")) {
                    arr[i] = '3';
                } else if ("ghi".contains(num + "")) {
                    arr[i] = '4';
                } else if ("jkl".contains(num + "")) {
                    arr[i] = '5';
                } else if ("mno".contains(num + "")) {
                    arr[i] = '6';
                } else if ("pqrs".contains(num + "")) {
                    arr[i] = '7';
                } else if ("tuv".contains(num + "")) {
                    arr[i] = '8';
                } else if ("wxyz".contains(num + "")) {
                    arr[i] = '9';
                } else if (num>='A' && num<='Y') {
                    arr[i] = (char) (num + 33);
                } else if (num =='Z') {
                    arr[i] = 'a';
                } else{
                    System.out.println("your password is error!");
                    return;
                }
            }
            for (char c : arr) {
                System.out.print(c);
            }
        }
    }

}

14.删除出现次数最少的字符

实现删除字符串中出现次数最少的字符,若多个字符出现次数一样,则都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。
注意每个输入文件有多组输入,即多个字符串用回车隔开

输入描述:

字符串只包含小写英文字母, 不考虑非法输入,输入的字符串长度小于等于20个字节。

输出描述:

删除字符串中出现次数最少的字符后的字符串。

示例1

输入

abcdd

输出

dd
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.TreeMap;


public class Main {

    /*public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String s = input.nextLine();
            Map<Character, Integer> map = new TreeMap<>();
            for (int i = 0; i < s.length(); i++) {
                char key = s.charAt(i);
                if (map.containsKey(key)) {
                    map.put(key, map.get(key) + 1);
                } else {
                    map.put(key, 1);
                }
            }
    
            List<Map.Entry<Character, Integer>> list = new ArrayList<>(map.entrySet());
            Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>() {
                @Override
                public int compare(Entry<Character, Integer> o1, Entry<Character, Integer> o2) {
                    return o1.getValue() - o2.getValue();
                }
            });
            String newS = s.replace(list.get(0).getKey() + "", "");
            for (int i = 1; i < list.size(); i++) {
                if (list.get(0).getValue() == list.get(i).getValue()) {
                    newS = newS.replace(list.get(i).getKey() + "", "");
                }else {
                    break;
                }
            }
            System.out.println(newS);
        }
        input.close();
    }*/

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String str = input.nextLine();
            int[] count = new int[26];
            char[] chs = str.toCharArray();
            int min = Integer.MAX_VALUE;
            for (int i = 0; i < chs.length; i++) {
                count[chs[i] - 'a']++;
                min = min > count[chs[i] - 'a'] ? count[chs[i] - 'a'] : min;
            }
            for (int i = 0; i < count.length; i++) {
                if (count[i] == min) {
                    str = str.replaceAll(String.valueOf((char) (i + 'a')), "");
                }
            }
            System.out.println(str);
        }
        input.close();
    }
}

15.蛇形矩阵

蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。

样例输入

5

样例输出

1 3 6 10 15

2 5 9 14

4 8 13

7 12

11

import java.util.Scanner;


public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            int N = Integer.parseInt(input.nextLine());
            int[][] m = new int[N][N];
            m[0][0] = 1; //核心思想,后一项与前一项的关系
            System.out.print(m[0][0] + " ");
            for (int i = 0; i < N - 1; i++) {
                m[i + 1][0] = m[i][0] + i + 1;
                for (int j = 0; j < N - 1 - i; j++) {
                    m[i][j + 1] = m[i][j] + j + i + 2;
                    System.out.print(m[i][j + 1] + " ");
                }
                System.out.print("\n" + m[i + 1][0] + " ");
            }
            System.out.println(); //注意在每个测试用例后添加换行
        }
        input.close();
    }
}

16.顺时针打印矩阵

package nowcode;


/**
 * 顺时针打印矩阵
 *     输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
 *     例如,如果输入如下4 X 4矩阵:
 *          1  2  3  4 
 *          5  6  7  8 
 *          9 10 11 12 
 *          13 14 15 16 
 *     则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
 */
public class T22printMatrixInCircle {

    public static void main(String[] args) {
        int[][] m = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
        int rows = m.length;
        int cols = m[0].length;
        int start = 0;
        while (cols > 2 * start && rows > 2 * start) {
            pringMatrixInCircle(m, rows, cols, start);
            start++;
        }
    }

    public static void pringMatrixInCircle(int[][] m, int rows, int cols, int start) {
        //1.从左到右打印
        for (int j = start; j < cols - start; j++) {
            System.out.print(m[start][j] + " ");
        }

        //2.从上到下
        for (int i = start + 1; i < rows - start; i++) {
            System.out.print(m[i][cols - start - 1] + " ");
        }

        //3.从右到左
        for (int j = cols - start - 2; j >= start; j--) {
            System.out.print(m[rows - start - 1][j] + " ");
        }

        //4.从下到上
        for (int i = rows - start - 2; i > start; i--) {
            System.out.print(m[i][start] + " ");
        }
    }
}

17.字符串加密

package nowcode;

import java.util.LinkedHashSet;
import java.util.Scanner;
import java.util.Set;

/**
 * 有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙。下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS。如果单词中包含有重复的字母,只保留第1个,其余几个丢弃。现在,修改过的那个单词属于字母表的下面,如下所示:
    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    T R A I L B Z E S C D F G H J K M N O P Q U V W X Y
    上面其他用字母表中剩余的字母填充完整。在对信息进行加密时,信息中的每个字母被固定于顶上那行,并用下面那行的对应字母一一取代原文的字母(字母字符的大小写状态应该保留)。因此,使用这个密匙,Attack AT DAWN(黎明时攻击)就会被加密为Tpptad TP ITVH。
    通过指定的密匙和明文得到密文。
    
    输入描述:
    先输入key和要加密的字符串
    
    输出描述:
    返回加密后的字符串
    
    示例1
    输入
    nihao
    ni
    输出
    le
 */
public class T23字符串加密 {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String s1 = "abcdefghijklmnopqrstuvwxyz";
        while (input.hasNext()) {
            StringBuffer sb = new StringBuffer(s1);
            String str = input.nextLine();
            String data = input.nextLine();
            String disStr = getDistinctString(str);
            //            System.out.println(disStr);

            String key = completion(sb, disStr);
            //            System.out.println(key);
            String result = getPlainText(key, data);
            System.out.println(result);
        }
    }

    /**
     * 字符串去重
     */
    public static String getDistinctString(String s) {
        Set<Character> set = new LinkedHashSet<>();
        for (int i = 0; i < s.length(); i++) {
            set.add(s.charAt(i));
        }
        String res = "";
        for (Character ch : set) {
            res += ch;
        }
        return res;
    }

    /**
     * 字符串补齐
     * @param sb:标准字符串
     * @param str:去重之后的字符串
     * @return 
     */
    public static String completion(StringBuffer sb, String str) {
        //int index = 0;
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);

            sb.deleteCharAt(sb.indexOf(ch + ""));
            //sb.insert(index++, ch);
        }
        return str + sb.toString();
    }

    /**
     * 得到明文
     * @param key:密钥
     * @param data:加密的数据
     * @return
     */
    public static String getPlainText(String key, String data) {
        String res = "";
        for (int i = 0; i < data.length(); i++) {
            char ch = data.charAt(i);
            if (Character.isLowerCase(ch)) {
                res += key.charAt(ch - 'a');
            } else if (Character.isUpperCase(ch)) {
                res += (char) (key.charAt(ch - 'A') - 32);
            } else {
                System.out.println("wrong");
                return null;
            }
        }
        return res;
    }
}

18.最长递增子序列

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String str = input.nextLine();
            String[] arr = str.split(" ");
            int[] nums = new int[arr.length];
            for (int i = 0; i < nums.length; i++) {
                nums[i] = Integer.parseInt(arr[i]);
            }
            int res = getMaxLengthOfSubsequence(nums);
            System.out.println(res);
        }
        input.close();
    }

    //获得最长子序列
    public static int getMaxLengthOfSubsequence(int[] nums) {
        int n = nums.length;
        int[] ls = new int[n];
        int res = 1;

        for (int i = 0; i < n; i++) {//填充ls
            int maxValue = 1;
            ls[i] = 1;
            for (int j = 0; j < i; j++) { ///遍历所有的A
                if (nums[i] > nums[j]) {
                    maxValue = max(maxValue, ls[j] + 1);
                }
                ls[i] = maxValue;
            }
        }

        int index = 0;
        //最长子序列末尾出现的位置
        for (int i = 0; i < n; i++) { //查找最大的子序列
            if (ls[i] > res) {
                res = ls[i];
                index = i;
            }
        }
        
        int count = res; //从后往前找子序列
        int[] arrRes = new int[count];
        arrRes[--count] = nums[index];
        for (int i = index; i >= 0; i--) {
            if (nums[i] < nums[index] && ls[i] == ls[index] - 1) {
                arrRes[--count] = nums[i];
                index = i;
            }
        }

        System.out.println(Arrays.toString(arrRes));
        return res;
    }

    public static int max(int a, int b) {
        return a > b ? a : b;
    }

}

19.合唱队

package nowcode2;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 计算最少出列多少位同学,使得剩下的同学排成合唱队形
    说明:
    N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 
    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,   则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。 
    你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。 
    
    输入描述:
    整数N
    
    输出描述:
    最少需要几位同学出列
    
    示例1
    输入
    8
    186 186 150 200 160 130 197 200
    输出
    4
 */
public class T25合唱队 {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            int num = Integer.parseInt(input.nextLine());
            String str = input.nextLine();
            String[] snum = str.split(" ");
            int[] nums = new int[num];
            for (int i = 0; i < num; i++) {
                nums[i] = Integer.parseInt(snum[i]);
            }

            int[] l1 = new int[num];
            int[] l2 = new int[num];

            int res = getMaxLenOfSubsequence(nums, l1, l2, num);
            System.out.println(res);
        }
        input.close();
    }

    public static int getMaxLenOfSubsequence(int[] nums, int[] l1, int[] l2, int num) {
        // 核心思想:动态规划 li = max(lj) +1,其中  0 <= j <i。
        for (int i = 0; i < num; i++) {//由左向右遍历
            l1[i] = 1;
            for (int j = 0; j < i; j++) { 
                if (nums[i] > nums[j] && l1[i] < l1[j] + 1) {
                    l1[i] = l1[j] + 1;
                }
            }
        }
        for (int i = num - 1; i >= 0; i--) { //从右向左遍历
            l2[i] = 1;
            for (int j = i + 1; j < num; j++) {
                if (nums[i] > nums[j] && l2[i] < l2[j] + 1) {
                    l2[i] = l2[j] + 1;
                }
            }
        }

        int res = 0;
        for (int i = 0; i < num; i++) {
            if (res < l1[i] + l2[i] - 1) {
                res = l1[i] + l2[i] - 1;
            }
        }
        return num - res;
    }
}

20.数据分类处理

输入描述:

一组输入整数序列I和一组规则整数序列R,I和R序列的第一个整数为序列的个数(个数不包含第一个整数);整数范围为0~0xFFFFFFFF,序列个数不限

输出描述:

从R依次中取出R<i>,对I进行处理,找到满足条件的I<j>: 

I<j>整数对应的数字需要连续包含R<i>对应的数字。比如R<i>为23,I<j>为231,那么I<j>包含了R<i>,条件满足 。 

按R<i>从小到大的顺序:

(1)先输出R<i>; 

(2)再输出满足条件的I<j>的个数; 

(3)然后输出满足条件的I<j>在I序列中的位置索引(从0开始); 

(4)最后再输出I<j>。 

附加条件: 

(1)R<i>需要从小到大排序。相同的R<i>只需要输出索引小的以及满足条件的I<j>,索引大的需要过滤掉 

(2)如果没有满足条件的I<j>,对应的R<i>不用输出 

(3)最后需要在输出序列的第一个整数位置记录后续整数序列的个数(不包含“个数”本身)

 

序列I:15,123,456,786,453,46,7,5,3,665,453456,745,456,786,453,123(第一个15表明后续有15个整数) 

序列R:5,6,3,6,3,0(第一个5表明后续有5个整数) 

输出:30, 3,6,0,123,3,453,7,3,9,453456,13,453,14,123,6,7,1,456,2,786,4,46,8,665,9,453456,11,456,12,786

说明:

30----后续有30个整数

3----从小到大排序,第一个R<i>为0,但没有满足条件的I<j>,不输出0,而下一个R<i>是3

6--- 存在6个包含3的I<j> 

0--- 123所在的原序号为0 

123--- 123包含3,满足条件 

 

示例1

输入

15 123 456 786 453 46 7 5 3 665 453456 745 456 786 453 123
5 6 3 6 3 0

输出

30 3 6 0 123 3 453 7 3 9 453456 13 453 14 123 6 7 1 456 2 786 4 46 8 665 9 453456 11 456 12 786
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

public class Main {
    /*
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            while (input.hasNext()) {
                String I = input.nextLine();
                String[] sarrI = I.substring(I.indexOf(" ") + 1).split(" ");
                String R = input.nextLine();
                String[] sarrR = R.substring(R.indexOf(" ") + 1).split(" ");
                int[] arrR = new int[sarrR.length];
                for (int i = 0; i < sarrR.length; i++) {
                    arrR[i] = Integer.parseInt(sarrR[i]);
                }
                //            System.out.println(Arrays.toString(sarrI));
                //            System.out.println(Arrays.toString(arrR));
    
                ArrayList<String> listR = sortAndDistinct(arrR);
                //            System.out.println(Arrays.toString(arrR));
                ArrayList<Integer> listRes = new ArrayList();
    //            System.out.println(listR);
                
                for (int i = 0; i < listR.size(); i++) {
                    listRes.add(Integer.parseInt(listR.get(i)));
                    ArrayList<String> listNums = new ArrayList<>();
                    ArrayList<Integer> listIndexs = new ArrayList<>();
                    for (int j = 0; j < sarrI.length; j++) {
                        if (sarrI[j].contains(listR.get(i))) {
                            listNums.add(sarrI[j]);
                            listIndexs.add(j);
                        }
                    }
                    
                    if(listNums.size()== 0) {
                        listRes.remove(listRes.size()-1); 
                        continue;
                    }
                    
                    listRes.add(listNums.size());
                    
                    for(int k = 0; k< listNums.size();k++) {
                        listRes.add(listIndexs.get(k));
                        listRes.add(Integer.parseInt(listNums.get(k)));
                    }
                }
                
                System.out.print(listRes.size()+" ");
                for (Integer val :listRes ) {
                    System.out.print(val + " ");
                }
    
            }
            input.close();
        }
    
        public static ArrayList<String> sortAndDistinct(int[] arr) {
            Arrays.sort(arr);
            LinkedHashSet<Integer> set = new LinkedHashSet<>();
            for (int i = 0; i < arr.length; i++) {
                set.add(arr[i]);
            }
    
            ArrayList<String> list = new ArrayList<>();
            for (Integer i : set) {
                list.add(String.valueOf(i));
            }
            return list;
        }*/

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String strI = input.nextLine();
            String strR = input.nextLine();
            String res = fun(strI, strR);
            System.out.println(res);
        }
        input.close();
    }

    public static String fun(String strI, String strR) {
        String[] arrI = strI.split(" ");
        String[] arrR = strR.split(" ");

        Set<Integer> setR = new TreeSet<>(); //有序的无重复数字可以用TreeSet
        for (int i = 1; i < arrR.length; i++) {
            setR.add(Integer.parseInt(arrR[i]));
        }

        StringBuffer result = new StringBuffer();

        for (int rdata : setR) {
            int num = 0;
            StringBuffer sb = new StringBuffer();

            for (int i = 1; i < arrI.length; i++) {
                if (arrI[i].contains(String.valueOf(rdata))) {
                    num++;
                    sb.append((i - 1) + " ");
                    sb.append(arrI[i] + " ");
                }
            }

            if (num != 0) {
                result.append(rdata + " ");
                result.append(num + " ");
                result.append(sb);
            }
        }
        int all_num = result.toString().split(" ").length;
        result.insert(0, (all_num) + " ");
        return result.toString();
    }
}

21.字符串排序

package nowcode2;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 题目描述
    编写一个程序,将输入字符串中的字符按如下规则排序。
    规则 1 :英文字母从 A 到 Z 排列,不区分大小写。
    如,输入: Type 输出: epTy
    规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。
    如,输入: BabA 输出: aABb
    规则 3 :非英文字母的其它字符保持原来的位置。
    如,输入: By?e 输出: Be?y
    
    输入描述:
    输入字符串
    输出描述:
    输出字符串
    示例1
    输入
    A Famous Saying: Much Ado About Nothing (2012/8).
    输出
    A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
 */
public class T27字符串排序 {

    /*public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String str = input.nextLine();
            char[] data = str.toCharArray();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < data.length; i++) {
                char ch = data[i];
                if (Character.isLetter(ch)) {
                    sb.append(ch);
                }
            }
            char[] sarr = sb.toString().toCharArray();
            getSortString(sarr);
    
            int index = 0;
            for (int i = 0; i < data.length; i++) {
                if (Character.isLetter(data[i])) {
                    System.out.print(sarr[index++]);
                } else {
                    System.out.print(data[i]);
                }
            }
            System.out.println();
        }
        input.close();
    }
    
    public static void getSortString(char[] sarr) {
        char temp = '*';
        for (int i = 0; i < sarr.length - 1; i++) {
            for (int j = sarr.length - 1; j > i; j--) {
                if (Character.toUpperCase(sarr[j - 1]) > Character.toUpperCase(sarr[j])) { //前面的字母比后面的字母小
                    temp = sarr[j - 1];
                    sarr[j - 1] = sarr[j];
                    sarr[j] = temp;
                } 
            }
        }
    }*/

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String str = input.nextLine();
            //            char[] arr = str.toCharArray();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < 26; i++) {
                char ch = (char) (i + 'A');
                for (int j = 0; j < str.length(); j++) {
                    if (ch == str.charAt(j) || ch == str.charAt(j) - 32) {
                        sb.append(str.charAt(j));
                    }
                }
            }

            for (int i = 0; i < str.length(); i++) {
                if (!Character.isLetter(str.charAt(i))) {
                    sb.insert(i, str.charAt(i));
                }
            }
            System.out.println(sb.toString());
        }
        input.close();
    }
}

22.查找兄弟单词

package nowcode2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class T28FindBrotherWords {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = null;
        while ((s = br.readLine()) != null) {
            String[] vals = s.split(" ");
            if (vals.length < 4)
                continue;
            int num = Integer.parseInt(vals[0]);
            if (num > 1000)
                continue;
            String key = vals[num + 1];
            int index = Integer.parseInt(vals[num + 2]);
            List<String> list = new ArrayList<String>();
            for (int i = 1; i <= num; i++) {
                if (isBrothStr(vals[i], key)) {
                    list.add(vals[i]);
                }
            }
            Collections.sort(list);
            System.out.println(list.size());
            if (list.size() >= index)
                System.out.println(list.get(index - 1));
        }
    }

    public static boolean isBrothStr(String source, String dest) {
        if (source.equals(dest) || source.length() != dest.length())
            return false;

        for (int i = 'a'; i <= 'z'; i++) {
            char ch = (char) i;
            if (getCharSize(source, ch) != getCharSize(dest, ch))
                return false;
        }
        return true;
        /*List<Character> list1 = new ArrayList<>();
        List<Character> list2 = new ArrayList<>();
        for (int i = 0; i < source.length(); i++) {
            list1.add(source.charAt(i));
            list2.add(dest.charAt(i));
        }
        System.out.println("list1:" + list1);
        System.out.println("list2:" + list2);
        return list1.containsAll(list2); // containsAll方法不能比较两个list是否相等,
                                            //反例:list1:[a, b, c, b]和list2:[a, c, a, b]也是true
        */

    }

    public static int getCharSize(String source, char ch) {
        int count = 0;
        for (int i = 0; i < source.length(); i++)
            if (source.charAt(i) == ch)
                count++;
        return count;
    }

}

23.字符串加密

 

package nowcode2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
/**
 * 题目描述
    1、对输入的字符串进行加解密,并输出。
    2加密方法为:
    当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;
    当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;
    其他字符不做变化。
    3、解密方法为加密的逆过程。
    
    说明:
    1、字符串以\0结尾。
    2、字符串最长100个字符。
    说明:
    
    1、字符串以\0结尾。
    2、字符串最长100个字符。
        
    输入描述:
    输入说明
    输入一串要加密的密码
    输入一串加过密的密码
    
    输出描述:
    输出说明
    输出加密后的字符
    输出解密后的字符
    
    示例1
    输入
    abcdefg
    BCDEFGH
    输出
    BCDEFGH
    abcdefg
 */
public class T30StringEncrption {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        while ((str = br.readLine()) != null) {
            String s1 = str;
            String s2 = br.readLine();

            String res1 = encrption(s1);
            System.out.println(res1);
            String res2 = decrption(s2);
            System.out.println(res2);
        }
    }

    public static String encrption(String s) {
        char[] arr = s.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] >= 'a' && arr[i] < 'z') {
                sb.append((char) (arr[i] - 31));
            } else if (arr[i] == 'z') {
                sb.append('A');
            } else if (arr[i] >= 'A' && arr[i] < 'Z') {
                sb.append((char) (arr[i] + 33));
            } else if (arr[i] == 'Z') {
                sb.append('a');
            } else if (arr[i] >= '0' && arr[i] < '9') {
                sb.append((char) (arr[i] + 1));
            } else if (arr[i] == '9') {
                sb.append('0');
            }
        }
        return sb.toString();
    }

    public static String decrption(String s) {
        char[] arr = s.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {

            if (arr[i] > 'a' && arr[i] <= 'z') {
                sb.append((char) (arr[i] - 33));
            } else if (arr[i] == 'a') {
                sb.append('Z');
            } else if (arr[i] > 'A' && arr[i] <= 'Z') {
                sb.append((char) (arr[i] + 31));
            } else if (arr[i] == 'A') {
                sb.append('z');
            } else if (arr[i] > '0' && arr[i] <= '9') {
                sb.append((char) (arr[i] - 1));
            } else if (arr[i] == '0') {
                sb.append('9');
            }
        }
        return sb.toString();
    }
}

24.字符串加密

package nowcode2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
/**
 * 题目描述
    1、对输入的字符串进行加解密,并输出。
    2加密方法为:
    当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;
    当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;
    其他字符不做变化。
    3、解密方法为加密的逆过程。
    
    说明:
    1、字符串以\0结尾。
    2、字符串最长100个字符。
    说明:
    
    1、字符串以\0结尾。
    2、字符串最长100个字符。
        
    输入描述:
    输入说明
    输入一串要加密的密码
    输入一串加过密的密码
    
    输出描述:
    输出说明
    输出加密后的字符
    输出解密后的字符
    
    示例1
    输入
    abcdefg
    BCDEFGH
    输出
    BCDEFGH
    abcdefg
 */
public class T30StringEncrption {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        while ((str = br.readLine()) != null) {
            String s1 = str;
            String s2 = br.readLine();

            String res1 = encrption(s1);
            System.out.println(res1);
            String res2 = decrption(s2);
            System.out.println(res2);
        }
    }

    public static String encrption(String s) {
        char[] arr = s.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] >= 'a' && arr[i] < 'z') {
                sb.append((char) (arr[i] - 31));
            } else if (arr[i] == 'z') {
                sb.append('A');
            } else if (arr[i] >= 'A' && arr[i] < 'Z') {
                sb.append((char) (arr[i] + 33));
            } else if (arr[i] == 'Z') {
                sb.append('a');
            } else if (arr[i] >= '0' && arr[i] < '9') {
                sb.append((char) (arr[i] + 1));
            } else if (arr[i] == '9') {
                sb.append('0');
            }
        }
        return sb.toString();
    }

    public static String decrption(String s) {
        char[] arr = s.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {

            if (arr[i] > 'a' && arr[i] <= 'z') {
                sb.append((char) (arr[i] - 33));
            } else if (arr[i] == 'a') {
                sb.append('Z');
            } else if (arr[i] > 'A' && arr[i] <= 'Z') {
                sb.append((char) (arr[i] + 31));
            } else if (arr[i] == 'A') {
                sb.append('z');
            } else if (arr[i] > '0' && arr[i] <= '9') {
                sb.append((char) (arr[i] - 1));
            } else if (arr[i] == '0') {
                sb.append('9');
            }
        }
        return sb.toString();
    }
}

25.小球弹落

package nowcode2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 假设一个球从任意高度自由落下,每次落地后反跳回原高度的一半; 再落下, 求它在第5次落地时,共经历多少米?第5次反弹多高? 
    输入描述:
    输入起始高度,int型
    输出描述:
    分别输出第5次落地时,共经过多少米第5次反弹多高
    
    示例1
    输入
    1
    输出
    2.875
    0.03125
*/
public class T39BallRebounce {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            double h = Double.parseDouble(str);
            double sum = h;
            h = h / 2;
            int times = 5;
            for (int i = 1; i < times; i++) {
                sum += h * 2;
                h = h / 2;
            }
            System.out.println(String.format("%.0f", sum));
            System.out.println(String.format("%.2f", h));
        }
    }
}

26.砝码称重

package nowcode2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
 * 题目描述
    现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
    每种砝码对应的数量为x1,x2,x3...xn。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
    
    注:
    称重重量包括0
    方法原型:public static int fama(int n, int[] weight, int[] nums)
    
    输入描述:
    输入包含多组测试数据。
    对于每组测试数据:
    第一行:n --- 砝码数(范围[1,10])
    第二行:m1 m2 m3 ... mn --- 每个砝码的重量(范围[1,2000])
    第三行:x1 x2 x3 .... xn --- 每个砝码的数量(范围[1,6])
    输出描述:
    利用给定的砝码可以称出的不同的重量数
    
    示例1
    输入
    2
    1 2
    2 1
    输出
    5
*/
public class T41砝码 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            int n = Integer.parseInt(str);
            int[] weight = new int[n];
            int[] nums = new int[n];

            String[] sarrw = bf.readLine().split(" ");
            String[] sarrn = bf.readLine().split(" ");
            for (int i = 0; i < n; i++) {
                weight[i] = Integer.parseInt(sarrw[i]);
                nums[i] = Integer.parseInt(sarrn[i]);
            }
            System.out.println(fama(n, weight, nums));
        }
    }

    private static int fama(int n, int[] weight, int[] nums) {
        // TODO Auto-generated method stub
        int maxWeight = 0;
        //所有砝码能够表示的最大重量
        for (int i = 0; i < n; i++) {//砝码的种类数
            maxWeight = maxWeight + nums[i] * weight[i];
        }
        boolean[] wflag = new boolean[maxWeight + 1];
        wflag[0] = true;//默认重量为0也是可以表示的
        wflag[maxWeight] = true;
        for (int i = 0; i < n; i++) {//砝码的种类数
            for (int j = 0; j < nums[i]; j++) {//每种砝码的个数
                for (int k = maxWeight; k >= weight[i]; k--) {//每种砝码的单个重量
                    if (wflag[k - weight[i]]) {
                        wflag[k] = true;
                    }
                }
            }
        }
        int count = 0;
        for (boolean b : wflag) {
            if (b)
                count++;
        }
        return count;
    }
}

27.走迷宫

package nowcode2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import tool.*;
/**
 * 题目描述
    定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示: 
    int maze[5][5] = {
            0, 1, 0, 0, 0,
            0, 1, 0, 1, 0,
            0, 0, 0, 0, 0,
            0, 1, 1, 1, 0,
            0, 0, 0, 1, 0,
    };
    它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。
    Input
    一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
    Output
    左上角到右下角的最短路径,格式如样例所示。
    
    输入描述:
    输入两个整数,分别表示二位数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
    
    输出描述:
    左上角到右下角的最短路径,格式如样例所示。
    
    示例1
    输入
    5 5
    0 1 0 0 0
    0 1 0 1 0
    0 0 0 0 0
    0 1 1 1 0
    0 0 0 1 0
    输出
    (0,0)
    (1,0)
    (2,0)
    (2,1)
    (2,2)
    (2,3)
    (2,4)
    (3,4)
    (4,4)
 */
public class T42走迷宫 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            String[] sarr = str.split(" ");
            int N = Integer.parseInt(sarr[0]);
            int M = Integer.parseInt(sarr[1]);
            //System.out.println(N + " " + M);
            int[][] matrix = new int[N][M];
            for (int i = 0; i < N; i++) {
                String[] arr1 = bf.readLine().split(" ");
                for (int j = 0; j < M; j++) {
                    matrix[i][j] = Integer.parseInt(arr1[j]);
                }
            }
            //Tookit.printArray(matrix);
            findShortestPath(matrix);
        }
    }

    public static void findShortestPath(int[][] maza) {
        //不考虑多解情况,迷宫只有一条通道
        //可以横着走或者竖着走
        int row = 0;
        int col = 0;
        while (row < maza.length) {
            while (col < maza[0].length) {
                if (maza[row][col] == 0) { 
                    printPath(row, col);
                    col++;//
                } else {//
                    col--;
                    row++;
                }
            }
            row++;
            if (col == maza[0].length)
                col--;//
        }
    }

    public static void printPath(int i, int j) {
        System.out.println("(" + i + "," + j + ")");
    }
}

28.数独

问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个粗线宫内的数字均含1-9,并且不重复。

输入:
包含已知数字的9X9盘面数组[空缺位以数字0表示]
输出:
完整的9X9盘面数组

输入描述:

包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出描述:

完整的9X9盘面数组

示例1

输入

0 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
0 4 5 2 7 6 8 3 1

输出

5 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
9 4 5 2 7 6 8 3 1
package nowcode2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;

import tool.*;

public class T43数独 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            int[][] matrix = new int[9][9];
            String[] sarr = str.split(" ");
            for (int j = 0; j < 9; j++) {
                matrix[0][j] = Integer.parseInt(sarr[j]);
            }
            for (int i = 1; i < 9; i++) {
                String[] temp = bf.readLine().split(" ");
                for (int j = 0; j < 9; j++) {
                    matrix[i][j] = Integer.parseInt(temp[j]);

                }
            }
            solveSudoku(matrix);
            Tookit.printArray(matrix);

        }
        bf.close();
    }

    static int solveSudoku(int[][] board) {
        int depth = 0;
        for (int i[] : board)
            for (int j : i)
                if (j == 0)
                    depth++;
        return dfs(board, depth);

    }

    static int dfs(int[][] board, int depth) {
        if (depth == 0)
            return 0;
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (board[i][j] == 0) {
                    if (board[6][0] == 2 && board[6][1] == 1 && board[6][2] == 3)
                        board[6][2] = 5;
                    for (int k = 1; k <= 10; k++) {
                        if (k == 10)
                            return depth;
                        board[i][j] = k;
                        if (!isValid(board, i, j))
                            board[i][j] = 0;
                        else {
                            depth--;
                            depth = dfs(board, depth);
                            if (depth == 0)
                                return depth;
                            depth++;
                            board[i][j] = 0;
                        }
                    }
                }
            }
        }
        return depth;
    }

    static boolean isValid(int[][] board, int row, int col) {
        boolean[] check = new boolean[10];
        for (int i = 0; i < check.length; i++)
            check[i] = true;
        for (int i = 0; i < board[0].length; i++) {
            if (check[board[row][i]])
                check[board[row][i]] = false;
            else if (board[row][i] != 0)
                return false;
        }

        for (int i = 0; i < check.length; i++)
            check[i] = true;
        for (int i = 0; i < board.length; i++) {
            if (check[board[i][col]])
                check[board[i][col]] = false;
            else if (board[i][col] != 0)
                return false;
        }

        for (int i = 0; i < check.length; i++)
            check[i] = true;
        int rowTemp = (row / 3) * 3;
        int colTemp = (col / 3) * 3;
        for (int k = 0; k < 9; k++) {
            row = rowTemp + k / 3;
            col = colTemp + k % 3;
            if (check[board[row][col]])
                check[board[row][col]] = false;
            else if (board[row][col] != 0)
                return false;
        }
        return true;
    }
}

29.括号匹配

package nowcode2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * 给定一个字符串,其中的字符只包含三种括号:花括号{ }、中括号[ ]、圆括号( ),即它仅由 “( ) [ ] { }” 这六个字符组成。
 * 设计算法,判断该字符串是否有效,即字符串中括号是否匹配。括号匹配要求括号必须以正确的顺序配对,如 “{ [ ] ( ) }”
 * 或 “[ ( { } [ ] ) ]”或 “{brace*&^[square(round)]end}”等为正确的格式,而 “[ ( ] )” 或 “{ [ ( ) }” 或 “( { } ] )” 
 * 或“{brace*&^[square(round])end}”均为不正确的格式。
 */
public class T44括号匹配 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            boolean res = bracketCheck(str);
            System.out.println(res);
        }
    }

    private static boolean bracketCheck(String s) {
        Map<Character, Character> bracketMap = new HashMap<>();
        bracketMap.put('}', '{');
        bracketMap.put(')', '(');
        bracketMap.put(']', '[');

        String bracketLeft = "{([";
        String bracketRight = "}])";

        Stack<Character> stack = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            //如果是左括号
            if (bracketLeft.contains(c + "")) {
                stack.add(c);//入栈
                //如果是右括号
            } else if (bracketRight.contains(c + "")) {
                //stack不为空,并且括号匹配成功
                if (stack.size() > 0 && (stack.peek() == bracketMap.get(c))) {
                    stack.pop();//出栈
                } else {
                    return false;
                }
            }
        }
        return stack.size() == 0;//如果栈为空,则匹配上了
    }
}

30.计算器之加减乘除运算

输入描述:

输入一个算术表达式

输出描述:

得到计算结果

示例1

输入

3+2*{1+2*[-4/(8-6)+7]}

输出

25
package nowcode3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class T45计算器之加减乘除运算 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            str = format(str);
            System.out.println(getResult(str));
        }

    }

    /**
     * 进行四则运行
     *
     * @param s 输入一个算术表达式
     * @return 表达式结果
     */
    public static int getResult(String s) {
        // 操作符栈
        Stack<Character> optchars = new Stack<>();
        // 操作数栈
        Stack<Integer> optdata = new Stack<>();
        int index = 0;
        while (index < s.length()) {
            char c = s.charAt(index);
            // 如果是数字
            if (c >= '0' && c <= '9') {
                // 计算数字的值,可能会存在两位及以上的数字
                int opd = 0;
                while (index < s.length() && s.charAt(index) >= '0' && s.charAt(index) <= '9') {
                    opd = opd * 10 + (s.charAt(index) - '0'); //将字符转化成数字
                    index++;
                }
                optdata.add(opd); //将数字加入到操作数栈中
            }
            // 如果是操作符
            else {
                // 如果是左括号
                if (c == '(' || c == '[' || c == '{') {
                    optchars.add(c); //将左括号字符加入到操作符栈中
                }
                // 如果是右括号
                else if (c == ')' || c == ']' || c == '}') {
                    //要同时保证optchars.peek()操作符顶端的符号不能是'('或'['或'{',防止在有些数字的输入形式是(3)+2,此处的3不能计算
                    while (!optchars.isEmpty() && optchars.peek() != '(' && optchars.peek() != '[' && optchars.peek() != '{') {
                        calculate(optchars, optdata);//计算左右括号内的两个数据的运算
                    }
                    optchars.pop(); //
                }
                // 如果是乘或者除
                else if (c == '*' || c == '/') {
                    //虽然操作符是乘除,但是还要保证前面的操作符栈中不能含有括号,如果含有括号,则不能进行运算
                    while (!optchars.isEmpty() && (optchars.peek() == '*' || optchars.peek() == '/')) {
                        calculate(optchars, optdata);
                    }
                    // 操作符入栈
                    optchars.add(c);
                } else if (c == '+' || c == '-') {
                    while (!optchars.isEmpty() && (optchars.peek() == '*' || optchars.peek() == '/' || optchars.peek() == '+'
                            || optchars.peek() == '-')) {
                        calculate(optchars, optdata);
                    }
                    // 操作符入栈
                    optchars.add(c);
                }
                // 处理下一个字符
                index++;
            }
        }
        while (!optchars.isEmpty()) {
            calculate(optchars, optdata);
        }
        return optdata.pop();
    }

    /**
     * 求值操作,取optchars的最后一个操作符,optdata中的最后两个操作数
     * @param optchars 操作符栈
     * @param optdata 操作数栈
     */
    public static void calculate(Stack<Character> optchars, Stack<Integer> optdata) {
        // 取操作数栈中的最后一个操作符
        char opt = optchars.pop();
        // 取操作数
        int v2 = optdata.pop();
        int v1 = optdata.pop();
        // 计算
        int v = calculateTowData(v1, v2, opt);
        optdata.add(v);
    }

    /**
     * 将算术表达式归整,-5*3整理成0-5*3
     * @param s 算术表达式
     * @return 归整后的表达式
     */
    public static String format(String s) {
        // 去掉空格
        String t = s.replaceAll("(\\s)+", "");

        int index = 0;
        // 对所有的减号进行处理
        while ((index = t.indexOf('-', index)) >= 0) {//String.indexOf(String str,int index)
                                                        //从index的地方开始找,返回第一次出现的索引
            if (index == 0) {// 第一个字符是负号,要规格形式要加上0
                t = '0' + t;
            }
            // 如果不是第一个字符
            else {
                char c = t.charAt(index - 1);//负号前面的一个字符
                // 负号前面有括号,需要在前面加0
                if (c == '(' || c == '[' || c == '{') {
                    t = t.substring(0, index) + '0' + t.substring(index);
                }
            }
            index++;
        }
        return t;
    }

    /**
     * 计算 d1 operator d2,operator是加减乘除
     *
     * @param d1       操作数1
     * @param d2       操作数2
     * @param operator 操作符
     * @return 结果
     */
    public static int calculateTowData(int d1, int d2, char operator) {
        switch (operator) {
        case '+':
            return d1 + d2;
        case '-':
            return d1 - d2;
        case '*':
            return d1 * d2;
        case '/':
            return d1 / d2;
        default:
            // do nothing
        }
        return 0;
    }
}

31.名字的漂亮度

给出一个名字,该名字有26个字符串组成,定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和。
每个字母都有一个“漂亮度”,范围在1到26之间。没有任何两个字母拥有相同的“漂亮度”。字母忽略大小写。
给出多个名字,计算每个名字最大可能的“漂亮度”。 

输入描述:

整数N,后续N个名字

输出描述:

每个名称可能的最大漂亮程度

示例1

输入

2
zhangsan
lisi

输出

192
101
package nowcode3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import tool.*;

public class T46计算名字的漂亮度 {

    /*public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            int N = Integer.parseInt(str);
            for (int i = 0; i < N; i++) {
                String name = bf.readLine();
                int res = getNameBeautyDegree(name);
                System.out.println(res);
            }
        }
    }
    
    public static int getNameBeautyDegree(String name) {
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < name.length(); i++) {
            char c = name.charAt(i);
            if (!map.containsKey(c)) {
                map.put(c, 1);
            } else {
                map.put(c, map.get(c) + 1);
            }
        }
        List<Map.Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character, Integer>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>() {
    
            @Override
            public int compare(Entry<Character, Integer> o1, Entry<Character, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        int res = 0;
        int num = 26;
        for (Entry<Character, Integer> entry : list) {
            res += entry.getValue() * num--;
        }
        return res;
    }*/

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            int N = Integer.parseInt(str);
            for (int i = 0; i < N; i++) {
                String name = bf.readLine();
                int res = getNameBeautyDegree(name);
                System.out.println(res);
            }
        }
    }

    public static int getNameBeautyDegree(String s) {
        int res = 0;
        int n = 26;
        int[] arr = new int[n];
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (arr[c - 'a'] != 0) {
                arr[c - 'a']++;
            } else {
                arr[c - 'a'] = 1;
            }
        }
        Arrays.sort(arr);
        for (int i = arr.length - 1; i >= 0; i--) {
            if (arr[i] > 0) {
                res += arr[i] * n--;
            }
        }
        return res;
    }
}

32.计算字符串的距离

package nowcode3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class T48计算字符串的距离 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str1 = null;
        while ((str1 = bf.readLine()) != null) {
            String str2 = bf.readLine();
            int res = getEditDistance(str1, str2);
            System.out.println(res);
        }
    }

    public static int getEditDistance(String s1, String s2) {
        int len1 = s1.length();
        int len2 = s2.length();

        if (len1 == 0 || len2 == 0)
            return Math.max(len1, len2);
        int[][] dp = new int[len1 + 1][len2 + 1];
        for (int i = 0; i <= len1; i++) {
            dp[i][0] = i;
        }

        for (int j = 0; j <= len2; j++) {
            dp[0][j] = j;
        }

        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (s1.charAt(i-1) == s2.charAt(j-1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1;
                }

            }
        }
        return dp[len1][len2];
    }

    //三个数中的最小值
    public static int min(int a, int b, int c) {
        int temp = a < b ? a : b;
        return temp < c ? temp : c;
    }
}

33.对应编码

package nowcode3;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class T50对应编码 {

    public static void main(String[] args) throws Exception {

        String[] S = { "Faint signals, barely perceptible", "Very weak signals", "Weak signals", "Fair signals",
                "Fairly good signals", "Good signals", "Moderately strong signals", "Strong signals",
                "Extremely strong signals" };
        String[] R = { "unreadable", "barely readable, occasional words distinguishable",
                "readable with considerable difficulty", "readable with practically no difficulty",
                "perfectly readable" };
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            int r = Integer.parseInt(str.charAt(0) + "");
            int s = Integer.parseInt(str.charAt(1) + "");
            System.out.println(S[s - 1] +", "+ R[r - 1]+".");
        }
    }

}

34.两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
package leecode;

import java.util.HashMap;

import com.sun.org.apache.regexp.internal.recompile;

import tool.Tookit;

public class TowSum {
    // 方法1:暴力法,两层for循环
    /*public static int[] getTowSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums[j] == target) {
                    return new int[] { i, j };
                }
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }*/

    // 方法2:使用HashMap快速查找
    public static int[] getTowSum(int[] nums, int target) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int competent = target - nums[i];
            if (map.containsKey(competent)) {
                return new int[] { map.get(competent), i };
            }
            map.put(nums[i], i);
        }
        throw new IllegalArgumentException("No two sum solution");
    }

    public static void main(String[] args) {
        int[] nums = { 2, 7, 11, 15 };
        int target = 9;
        int[] res = getTowSum(nums, target);
        Tookit.printArray(res);
    }

}

35.两数字相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

官方题解

package leecode;

class ListNode {
    int val;
    ListNode next;

    public ListNode(int x) {
        this.val = x;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(this.val).append("->");

        ListNode node = this;
        while (node.next != null) {
            node = node.next;
            sb.append(node.val);

            if (node.next != null) {
                sb.append("->");
            }
        }
        return sb.toString();
    }
}

public class AddTowNumbers {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummyHead = new ListNode(0);// 头节点
        ListNode p1 = l1, p2 = l2;
        ListNode current = dummyHead;
        int carry = 0;
        while (p1 != null || p2 != null) {
            int x1 = (p1 != null) ? p1.val : 0;
            int x2 = (p2 != null) ? p2.val : 0;
            int sum = carry + x1 + x2;
            carry = sum / 10;
            current.next = new ListNode(sum % 10);
            current = current.next;
            if (p1 != null)
                p1 = p1.next;
            if (p2 != null)
                p2 = p2.next;
        }
        if (carry > 0) {
            current.next = new ListNode(carry);
        }
        return dummyHead.next;
    }

    public static void main(String[] args) {
        /*        int[] num1 = new int[] { 2, 4, 3 };
        int[] num2 = new int[] { 5, 6, 4 };
        
        ListNode l1 = new ListNode(0);
        ListNode node = l1;
        for (int i = 0; i < num1.length; i++) {
            node.val = num1[i];
            if (i < num1.length - 1) {
                node.next = new ListNode(0);
                node = node.next;
            }
        }
        System.out.println(l1);
        
        ListNode n2 = new ListNode(0);
        node = n2;
        for (int i = 0; i < num2.length; i++) {
            node.val = num2[i];
            if (i < num2.length - 1) {
                node.next = new ListNode(0);
                node = node.next;
            }
        }
        System.out.println(n2);*/
        
        ListNode l1 = new ListNode(2);
        ListNode node2 = new ListNode(4);
        ListNode node3 = new ListNode(3);
        l1.next = node2;
        node2.next = node3;
        System.out.println(l1);

        ListNode l2 = new ListNode(5);
        ListNode node5 = new ListNode(6);
        ListNode node6 = new ListNode(4);
        l2.next = node5;
        node5.next = node6;
        System.out.println(l2);
        
        ListNode res = new AddTowNumbers().addTwoNumbers(l1, l2);
        System.out.println(res);
        
    }

}

36.无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

官方题解

package leecode;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class T03_LengthOfLongestSubstring {

    /**
     * 方法1:暴力法
     *//*
        public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        int ans = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {// s的所有子串
                if (allUnique(s, i, j)) {
                    ans = Math.max(ans, j - i);
                }
            }
        }
        return ans;
        }
        
        // 检查子串中是否包含相同的元素
        public boolean allUnique(String s, int start, int end) {
        Set<Character> set = new HashSet<>();
        for (int i = start; i < end; i++) {
            Character ch = s.charAt(i);
            if (set.contains(ch))
                return false;
            set.add(ch);
        }
        return true;
        }
        */
    /**
     * 方法2
     *//*
        public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        Set<Character> set = new HashSet<>();
        int ans = 0, i = 0, j = 0;
        
        while (i < n && j < n) {
            // try to extend the range [i, j]
            if (!set.contains(s.charAt(j))) {
                set.add(s.charAt(j++));
                ans = Math.max(ans, j - i);
            } else {
                set.remove(s.charAt(i++));
            }
        }
        return ans;
        }*/
    /**
     * 方法3
     */
    public int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0, i = 0;
        HashMap<Character, Integer> map = new HashMap<>();
        for (int j = 0; j < n; j++) {
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            ans = Math.max(ans, j - i + 1);
            map.put(s.charAt(j), j + 1);
        }
        return ans;
    }

    public static void main(String[] args) {
        T03_LengthOfLongestSubstring s = new T03_LengthOfLongestSubstring();
        System.out.println(s.lengthOfLongestSubstring("bbbbb"));
        System.out.println(s.lengthOfLongestSubstring("abcabcbb"));
        System.out.println(s.lengthOfLongestSubstring("pwwkew"));
    }
}