【算法小试】笔试

本文探讨了一系列编程挑战,涵盖了从字符串处理、矩阵操作到数据分类和正则表达式应用等多个方面。通过解决这些挑战,我们可以深入了解如何在实际问题中应用计算机科学的基本原理,例如排序、搜索、数据结构和算法。这些挑战不仅锻炼了编程技巧,还展示了在复杂问题中寻找解决方案的过程。
摘要由CSDN通过智能技术生成

不保证正确性,仅供自我练习以及复习

1.流浪地球


流浪地球计划在赤道上均匀部署了N个转向发动机,按位置顺序编号为0~N-1。 1) 初始状态下所有的发动机都是未启动状态; 2) 发动机起动的方式分为“手动启动”和“关联启动”两种方式; 3) 如果在时刻1一个发动机被启动,下一个时刻2与之相邻的两个发动机就会被“关联启动”; 4) 如果准备启动某个发动机时,它已经被启动了,则什么都不用做; 5) 发动机0与发动机N-1是相邻; 地球联合政府准备挑选某些发动机在某些时刻进行“手动启动”,当然最终所有的发动机都会被启动。 哪些发动机最晚被启动呢? 输入描述:         第一行两个数字N和E,中间有空格         N代表部署发动机的总个数,E代表计划手动启动的发动机总个数         1<N<=1000,1<=E<=1000,E<=N         接下来共E行,每行都是两个数字T和P,中间有空格         T代表发动机的手动启动时刻,P代表此发动机的位置编号。         0<=T<=N,0<=P<=N 输出描述:         第一行一个数字N,以回车结束 N代表最后被启动的发动机个数         第二行N个数字,中间有空格,以回车结束         每个数字代表发动机的位置编号,从小到大排序

输入:
8 2
0 0
1 7

输出:
1
4
   //流浪地球
//    流浪地球计划在赤道上均匀部署了N个转向发动机,按位置顺序编号为0~N-1。
//            1) 初始状态下所有的发动机都是未启动状态;
//            2) 发动机起动的方式分为“手动启动”和“关联启动”两种方式;
//            3) 如果在时刻1一个发动机被启动,下一个时刻2与之相邻的两个发动机就会被“关联启动”;
//            4) 如果准备启动某个发动机时,它已经被启动了,则什么都不用做;
//            5) 发动机0与发动机N-1是相邻;
//    地球联合政府准备挑选某些发动机在某些时刻进行“手动启动”,当然最终所有的发动机都会被启动。
//    哪些发动机最晚被启动呢?
//
//    输入描述:
//    第一行两个数字N和E,中间有空格
//    N代表部署发动机的总个数,E代表计划手动启动的发动机总个数
//    1<N<=1000,1<=E<=1000,E<=N
//    接下来共E行,每行都是两个数字T和P,中间有空格
//    T代表发动机的手动启动时刻,P代表此发动机的位置编号。
//     0<=T<=N,0<=P<=N
//
//    输出描述:
//    第一行一个数字N,以回车结束 N代表最后被启动的发动机个数
//    第二行N个数字,中间有空格,以回车结束
//    每个数字代表发动机的位置编号,从小到大排序


    public static boolean hasNoRunning(int[] engines) {
        return Arrays.stream(engines).anyMatch(item -> item == -1);
    }

    public static void autoRunEngine(int[] engines, int index, int time, int length) {
        int left = index == 0 ? length - 1 : (index - 1);
        int right = index == length - 1 ? 0 : index + 1;
        engines[left] = engines[left] == -1 ? time : engines[left];
        engines[right] = engines[right] == -1 ? time : engines[right];
    }

    public static void findLatestEngine(int[] engines, int start) {
        boolean flag = true;
        while (flag) {
            for (int i = 0; i < engines.length; i++) {
                if (engines[i] == start) {
                    System.out.println(start + "编号:"+i);
                    autoRunEngine(engines, i, start + 1, engines.length);

                }
            }
            start++;
            System.out.println(Arrays.toString(engines));
            flag = hasNoRunning(engines);
        }
        int maxTime = Arrays.stream(engines).max().getAsInt();
        int count = 0;
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < engines.length; i++) {
            if(maxTime == engines[i]) {
                stringBuilder.append(i + " ");
                count++;
            }
        }
        System.out.println(count);
        System.out.println(stringBuilder.toString().trim());
    }


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int N = sc.nextInt();
            int E = sc.nextInt();

            int[] engines = new int[N];
            Arrays.fill(engines, -1);
            int minTime = Integer.MAX_VALUE;
            for (int i = 0; i < E; i++) {
                int time = sc.nextInt();
                int index = sc.nextInt();
                engines[index] = time;
                minTime = Math.min(minTime, time);
            }
            findLatestEngine(engines,minTime);
        }
    }

2.最大子矩阵

给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。
返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。
若有多个满足条件的子矩阵,返回任意一个均可。
以及返回最大和

这个属实很难,还是看的力扣题解。。。。

//    给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。
//    返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。
//    若有多个满足条件的子矩阵,返回任意一个均可。
//    以及返回最大和


    public static void getMaxMatrix(int[][] matrix,int N,int M) {
        int[] total = new int[M];
        int sum = 0;
        int maxSum = 0;
        int startX = 0, startY = 0;
        int[] res=new int[4];

        for (int i = 0; i < N; i++) {
            Arrays.fill(total,0);
            for (int j = i; j < N; j++) {
                sum = 0;
                for (int k = 0; k < M; k++) {
                    total[k] += matrix[j][k];
                    // 不需要记录具体子矩阵
                    // sum = Math.max(sum + total[k],total[k]);
                    // maxSum = Math.max(sum, maxSum);

                    // 记录矩阵左上角和右下角坐标
                    if(sum > 0) {
                        sum+= total[k];
                    } else {
                        sum = total[k];
                        startX = i;
                        startY = k;
                    }
                    if(sum>maxSum) {
                        maxSum = sum;
                        res[0] = startX;
                        res[1] = startY;
                        res[2] = j;
                        res[3] = k;
                    }
                }
            }
        }
        System.out.println(maxSum + "坐标:" + res[0] +","+res[1]+ ";" +res[2]+","+res[3]);
    }


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            String[] str = sc.nextLine().split(" ");
            int N = Integer.parseInt(str[0]);
            int M = Integer.parseInt(str[1]);
            int[][] arr = new int[N][M];
            for (int i = 0; i < N; i++) {
                String[] s = sc.nextLine().split(" ");
                for (int j = 0; j < M; j++) {
                    arr[i][j] = Integer.parseInt(s[j]);
                }
            }
            getMaxMatrix(arr, N, M);
        }
    }

3.最长连续子序列

有N个正整数组成的⼀个序列。给定整数sum,求⻓度最⻓的连续⼦序列,使他们的和等于
sum,返回此⼦序列的⻓度,如果没有满⾜要求的序列,返回-1。
示例1
输⼊
    1,2,3,4,2
    6
输出 3
说明:解释:1,2,3和4,2两个序列均能满⾜要求,所以最⻓的连续序列为1,2,3,因此结果为3
示例2
输⼊
   1,2,3,4,2
   20
输出  -1
说明:解释:没有满⾜要求的⼦序列,返回-1
备注: 输⼊序列仅由数字和英⽂逗号构成,数字之间采⽤英⽂逗号分隔;
    序列⻓度:1 <= N <= 200;
    输⼊序列不考虑异常情况,由题⽬保证输⼊序列满⾜要求。
    public static int findMaxLength(int[] arr, int target) {
        int maxLength = -1;


//        for (int i = 0; i < arr.length; i++) {
//            int temp = target;
//            for (int j = i; j < arr.length; j++) {
//                temp -= arr[j];
//                if(temp == 0) {
//                    maxLength = Math.max(maxLength, j-i+1);
//                    break;
//                } else if(temp < 0) {
//                    break;
//                }
//            }
//        }

        for (int i = 0; i < arr.length; i++) {
            int sum = 0;
            for (int j = i; j < arr.length; j++) {
                sum += arr[j];
                if (sum == target) {
                    maxLength = Math.max(maxLength, j - i + 1);
                    break;
                } else if (sum > target) {
                    break;
                }
            }
        }

        return maxLength;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String[] str = sc.nextLine().split(",");
            int target = Integer.parseInt(sc.nextLine());

            int[] arr = new int[str.length];
            for (int i = 0; i < str.length; i++) {
                arr[i] = Integer.parseInt(str[i]);
            }
            System.out.println(findMaxLength(arr, target));
        }
    }

4.分解自然数

题目描述
    一个整数可以由连续的自然数之和来表示 给定一个整数 计算该整数有几种连续自然数之和的表达式 并打印出每一种表达式

输入描述 一个目标整数t 1<= t <=1000
输出描述 该整数的所有表达式和表达式的个数。如果有多种表达式,输出要求为:
自然数个数最少的表达式优先输出
每个表达式中按自然数递增的顺序输出,具体的格式参见样例。在每个测试数据结束时,输出一行”Result:X”,其中X是最终的表达式个数。
具体的格式参见样例
示例1
输入
    9
输出
    9=9
    9=4+5
    9=2+3+4
Result:3
说明
    整数 9 有三种表示方法,第1个表达式只有1个自然数,最先输出,
    第2个表达式有2个自然数,第2次序输出,
    第3个表达式有3个自然数,最后输出。
    每个表达式中的自然数都是按递增次序输出的。
    数字与符号之间无空格。
    public static void splitNum(int num, Stack<StringBuilder> stack) {
        int sum = 0, i = 1;
        int start = 1;

        while (i <= (num+1)/2) {
            sum += i;
            if (sum == num) {
                StringBuilder sb = new StringBuilder(num + "=");
                for (int j = start; j <= i; j++) {
                    if (j < i) {
                        sb.append(j + "+");
                    } else {
                        sb.append(j);
                    }
                }
                stack.push(sb);
            } else if (sum > num) {
                i = start;
                start++;
                sum = 0;
            }
            i++;
        }
        stack.push(new StringBuilder(num+"="+num));
    }

//    public static void splitNum2(int num, Stack<StringBuilder> stack) {
//        int sum = 0;
//        int start = 1, end = 1;
//
//        while (start <= (num+1)/2) {
//            if (sum == num) {
//                System.out.println(sum+";"+end);
//                StringBuilder sb = new StringBuilder(num + "=");
//                for (int j = start; j <= end; j++) {
//                    if (j < end) {
//                        sb.append(j + "+");
//                    } else {
//                        sb.append(j);
//                    }
//                }
//                stack.push(sb);
//                start++;
//                end = start;
//                sum = 0;
//            } else if (sum > num) {
//                sum -= start ;
//                start ++;
//            } else {
//                sum+=end;
//                end++;
//            }
//        }
//    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int num = sc.nextInt();
            Stack<StringBuilder> stack = new Stack<>();
            splitNum(num, stack);
            int size = stack.size();;
            while(!stack.isEmpty()) {
                System.out.println(stack.pop());
            }
            System.out.println("Result:"+size);
        }
    }

5. 相对开音节

    
相对开音节构成的结构为辅音+元音(aeiou)+辅音(r除外)+e,常见的单词有bike、cake等。给定一个字符串,以空格为分隔符,反转每个单词中的字母,若单词中包含如数字等其他非字母时不进行反转。反转后计算其中含有相对开音节结构的子串个数(连续的子串中部分字符可以重复)。
输入描述:
    字符串,以空格分割的多个单词,字符串长度<10000,字母只考虑小写
输出描述:
    含有相对开音节结构的子串个数,注:个数<10000
示例1
输入
    ekam a ekac
输出
    2
说明
    反转后为 make a cake 其中make、cake为相对开音节子串,返回2
示例2
输入
    !ekam a ekekac
输出
    2
说明
    反转后为!ekam a cakeke 因!ekam含非英文字符所以未反转,其中 cake、keke为相对开音节子串,返回2
    输入为一行字符串,定义一个名词叫音节:一个辅音,一个元音(aeiou),一个辅音(除了r),一个e。
    如果字符串中的单词只有字母,则单词反转。
    输出最多有几个音符。
    public static int getTotalCount(String[] str) {
        int total = 0;

        Pattern pattern = Pattern.compile("[^a-z]");
        for (int i = 0; i < str.length; i++) {
            if (!pattern.matcher(str[i]).find()) {
                StringBuilder stringBuilder = new StringBuilder(str[i]);
                String reverse = stringBuilder.reverse().toString();
                total += getCountFromWord(reverse);
            }
        }
        return total;
    }

    public static int getCountFromWord(String str) {
        if (str.length() < 4) return 0;
        int count = 0;
        int i = 0;
        while (i < str.length() - 3) {
            System.out.println(str.charAt(i) +" " +str.charAt(i + 1)+" "+str.charAt(i + 2)+" "+str.charAt(i + 3));
            if (!isVowel(str.charAt(i)) && isVowel(str.charAt(i + 1))
                    && !isVowel(str.charAt(i + 2)) && str.charAt(i + 2) != 'r' && str.charAt(i + 3) == 'e') {
                count++;
                i += 2;
            } else {
                i++;
            }
        }
        return count;
    }

    public static boolean isVowel(Character s) {
        String vowel = "aoeui";
//        System.out.println(s);
        return vowel.indexOf(s) != -1;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String[] s = sc.nextLine().split(" ");
            System.out.println(getTotalCount(s));
//            getTotalCount(s);
        }

    }

6.找朋友

在学校中,N个⼩朋友站成⼀队, 第i个⼩朋友的身⾼为height[i],
第i个⼩朋友可以看到的第⼀个⽐⾃⼰身⾼更⾼的⼩朋友j,那么j是i的好朋友(要求j > i)。
请重新⽣成⼀个列表,对应位置的输出是每个⼩朋友的好朋友位置,如果没有看到好朋友,请 在该位置⽤0代替。
⼩朋友⼈数范围是 [0, 40000]。
输⼊描述:
第⼀⾏输⼊N,N表示有N个⼩朋友
第⼆⾏输⼊N个⼩朋友的身⾼height[i],都是整数
输出描述:
输出N个⼩朋友的好朋友的位置

示例1
输⼊
2
100 95
输出
0 0

示例2
输⼊
8
123 124 125 121 119 122 126 123
输出
1 2 6 5 5 6 0 0
public static int[] findFriend(int[] arr) {
        int[] res = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            for (int j = i+1; j < arr.length; j++) {
                if (arr[j] > arr[i]) {
                    res[i] = j;
                    break;
                }
            }
        }
        return res;
    }

    public static void main(String[] ags){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int count = sc.nextInt();
            int[] arr = new int[count];
            for (int i = 0; i < count; i++) {
                arr[i] = sc.nextInt();
            }
            int[] res = findFriend(arr);
            for (int i = 0; i < count; i++) {
                System.out.printf("%d ",res[i]);
            }
            System.out.println();
        }
    }

7.按身高体重排序

题目描述:某学校举行运动会,学生们按编号(1、2、3…n)进行标识,现需要按照身高由低到高排列,对身高相同的人,按体重由轻到重排列;
对于身高体重都相同的人,维持原有的编号顺序关系。请输出排列后的学生编号。
输入描述:
两个序列,每个序列由 n 个正整数组成(0<n<=100)。第一个序列中的数值代表身高,第二个序列中的数值代表体重。
输出描述:
排列结果,每个数值都是原始序列中的学生编号,编号从 1 开始
    static class Student {
        int index;
        int height;
        int weight;

        public Student(int index, int height, int weight) {
            this.index = index;
            this.height = height;
            this.weight = weight;
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int count = sc.nextInt();
            int[] height = new int[count];
            int[] weight = new int[count];
            for (int i = 0; i < count; i++) {
                height[i] = sc.nextInt();
            }
            for (int i = 0; i < count; i++) {
                weight[i] = sc.nextInt();
            }
            List<Student> students = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                students.add(new Student(i + 1, height[i], weight[i]));
            }
            students.sort(new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    if (o1.height != o2.height) {
                        return o1.height - o2.height;
                    }
                    if(o1.weight != o2.weight) {
                        return o1.weight - o2.weight;
                    }
                    return o1.index - o2.index;
                }
            });

            String s = students.stream().map(item -> item.index + "").collect(Collectors.joining(" "));
            System.out.println(s);

        }
    }

8.数据分类

对⼀个数据a进⾏分类,分类⽅法为:此数据a(四个字节⼤⼩)的四个字节相加对⼀个给定
的值b取模,如果得到的结果⼩于⼀个给定的值c,则数据a为有效类型,其类型为取模的值;
如果得到的结果⼤于或者等于c,则数据a为⽆效类型。

⽐如⼀个数据a=0x01010101,b=3,按照分类⽅法计算(0x01+0x01+0x01+0x01)%3=1,
所以如果c=2,则此a为有效类型,其类型为1,如果c=1,则此a为⽆效类型;
⼜⽐如⼀个数据a=0x01010103,b=3,按照分类⽅法计算(0x01+0x01+0x01+0x03)%3=0,
所以如果c=2,则此a为有效类型,其类型为0,如果c=0,则此a为⽆效类型。

输⼊12个数据,第⼀个数据为c,第⼆个数据为b,剩余10个数据为需要分类的数据,请找到
有效类型中包含数据最多的类型,并输出该类型含有多少个数据。
输⼊描述:
输⼊12个数据,⽤空格分隔,第⼀个数据为c,第⼆个数据为b,剩余10个数据为需要分类的
数据。
输出描述:
输出最多数据的有效类型有多少个数据。
    public static int getValidType(int num, int b, int c) {
        int sum = 0;
        for (int i = 0; i < 4; i++) {
            sum += num>>8*i &0xff;
        }
        return sum%b <c ?sum%b :-1;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int c = sc.nextInt();
            int b = sc.nextInt();

            int[] arr = new int[10];
            for (int i = 0; i < 10; i++) {
                arr[i] = sc.nextInt();
            }

            Map map = new HashMap<Integer,Integer>();
            int maxCount = 0;
            for (int i = 0; i < 10; i++) {
                int type = getValidType(arr[i],b,c);
                if(type != -1) {
                    int count = (int) map.getOrDefault(type,0);
                    if( count+1>maxCount) maxCount = count+1;
                    map.put(type, count+1);
                }
            }
            System.out.println(maxCount);
        }
    }

9.

有一个正整数数组, 每次从该数组中取出两个最大的数字做减法
(如果两个数字不相等,用大数减去小数,保证相减后的结果大于等于0),
如果相减的结果不为0 ,则将相减后的结果数字放回数组。然后再从数组中取两个最大的数字做减法,不断循环重复。
如果最后数组中只剩一个数字。请给出该数字的值,如果没有数字剩下给出0值即可
//    有一个正整数数组, 每次从该数组中取出两个最大的数字做减法
//    (如果两个数字不相等,用大数减去小数,保证相减后的结果大于等于0),
//    如果相减的结果不为0 ,则将相减后的结果数字放回数组。然后再从数组中取两个最大的数字做减法,不断循环重复。
//    如果最后数组中只剩一个数字。请给出该数字的值,如果没有数字剩下给出0值即可

    public static int playNum(List<Integer> list) {
        while(list.size() > 1) {
            Collections.sort(list);
            System.out.println(list);
            int max = list.remove(list.size()-1);
            int secondMax = list.remove(list.size()-1);
            if(max-secondMax > 0){
                list.add(max-secondMax);
            }
        }
        return list.size() > 0 ?list.get(0):0;
    }


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int count = Integer.parseInt(sc.nextLine());
        String[] s = sc.nextLine().split(" ");
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < s.length; i++) {
            list.add(Integer.parseInt(s[i]));
        }
        System.out.println(playNum(list));
    }

10.生成回文素数

给定一个整数N,生成不大于N的所有回文素数
public static boolean isPrime(int num) {
        if(num<2) return false;
        if(num == 2) return true;
        if(num %2 ==0) return false;
        for(int i =3;i*i<=num;i+=2) {
            if(num%i == 0) return false;
        }
        return true;
    }

    public static boolean isPalindrome(int num) {
        String s = String.valueOf(num);
        StringBuilder stringBuilder = new StringBuilder(s);
        return stringBuilder.reverse().toString().equals(s);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        StringBuilder stringBuilder = new StringBuilder();
        int count = 0;
        for(int i =1;i<=num;i++) {
            if(isPrime(i) && isPalindrome(i)) {
                count++;
                stringBuilder.append(i);
                stringBuilder.append(',');
            }
        }
        System.out.println(stringBuilder.insert(0,count+",").delete(stringBuilder.length()-1,stringBuilder.length()));
    }

11.最大括号深度

        现有⼀字符串仅由 '(' ')' '{' '}' '[' ']' 六种括号组成。
        若字符串满⾜以下条件之⼀,则为⽆效字符串:
                ①任⼀类型的左右括号数量不相等;
                ②存在未按正确顺序(先左后右)闭合的括号。
        输出括号的最⼤嵌套深度,若字符串⽆效则输出0
        0≤字符串⻓度 ≤100000
        输⼊描述:
                ⼀个只包括 '(', ')' '{' '}' '[' ']' 的字符串
        输出描述:
                ⼀个整数,最⼤的括号深度
        示例1
                输⼊
                []
                输出
                1
        示例2
                输⼊
                ([]{()})
                输出
                3
    private static final Map<String,String> map = new HashMap<String,String>(){
        {
            put(")","(");
            put("}","{");
            put("]","[");
        }
    };

    public int maxDepth(String str) {
        String[] arr = str.split("");
        Stack<String> stack = new Stack<>();

        int maxDepth = 0;
        for (int i = 0; i < arr.length; i++) {
            if(!stack.isEmpty() && stack.peek().equals(map.getOrDefault(arr[i], ""))) {
                maxDepth = Math.max(maxDepth,stack.size());
                stack.pop();
                continue;
            }
            stack.push(arr[i]);
        }
        if(stack.isEmpty()) {
            return maxDepth;
        }
        return 0;
    }

12. 寻找相同子串

给你两个字符串 t 和 p ,要求从 t 中找到一个和 p 相同的连续子串,并输出该字串第一个字符的下标。
输入描述:
输入文件包括两行,分别表示字符串 t 和 p ,保证 t 的长度不小于 p ,且 t 的长度不超过1000000,p 的长度不超过10000。
输出描述:
如果能从 t 中找到一个和 p 相等的连续子串,则输出该子串第一个字符在t中的下标(下标从左到右依次为1,2,3,…);
如果不能则输出”No”;如果含有多个这样的子串,则输出第一个字符下标最小的。
示例1
输入
    AVERDXIVYERDIAN
    RDXI
输出
    4
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str1 = sc.nextLine();
            String str2 = sc.nextLine();
            String res = str1.indexOf(str2) == -1 ? "No" : str1.indexOf(str2) + 1 + "";
            System.out.println(res);
        }
    }

13.滑动窗口最大和

有⼀个N个整数的数组,和⼀个⻓度为M的窗⼝,窗⼝从数组内的第⼀个数开始滑动直到窗⼝
不能滑动为⽌,每次窗⼝滑动产⽣⼀个窗⼝和(窗⼝内所有数的和),求窗⼝滑动产⽣的所有
窗⼝和的最⼤值。
输⼊描述:
第⼀⾏输⼊⼀个正整数N,表示整数个数。(0<N<100000)
第⼆⾏输⼊N个整数,整数的取值范围为[-100,100]。
第三⾏输⼊⼀个正整数M,M代表窗⼝⼤⼩,M<=100000,且M<=N。
输出描述:
窗⼝滑动产⽣的所有窗⼝和的最⼤值。
示例1:
输⼊
    6
    10 20 30 15 23 12
    3
输出
    68
说明 窗⼝⻓度为3,窗⼝滑动产⽣的窗⼝和分别为10+20+30=60,20+30+15=65,
    30+15+23=68,15+23+12=50,所以窗⼝滑动产⽣的所有窗⼝和的最⼤值为68。
    public static int getMaxFromWindows(int[] arr, int size) {
        int maxSum = 0;
        for (int i = 0; i <= arr.length - size; i++) {
            int sum = 0;
            for (int j = i; j < i + size; j++) {
                sum += arr[j];
            }
            maxSum = Math.max(sum, maxSum);
        }
        return maxSum;
    }
    public static int getMaxFromWindows2(int[] arr, int size) {
        int maxSum = 0, sum = 0;
        for (int i = 0; i < size; i++) {
            sum += arr[i];
        }
        maxSum = sum;
        if (arr.length > size) {
            for (int i = 1; i <= arr.length - size; i++) {
                sum = sum - arr[i - 1] + arr[i + size - 1];
                maxSum = Math.max(sum, maxSum);
            }
        }

        return maxSum;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int N = sc.nextInt();
            int[] arr = new int[N];
            for (int i = 0; i < N; i++) {
                arr[i] = sc.nextInt();
            }
            int M = sc.nextInt();
            System.out.println(getMaxFromWindows(arr, M));
        }

    }

14.最长子字符串的长度

给你⼀个字符串 s ,字符串 s ⾸尾相连成⼀个环形 ,请你在环中找出 'o' 字符出现了偶数
次最⻓⼦字符串的⻓度。
输⼊描述 :
        输⼊是⼀串⼩写字⺟组成的字符串
输出描述 :
        输出是⼀个整数
示例 1
输⼊
        alolobo
输出
        6
    public static int getMaxLength(String str) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) == 'o') {
                count++;
            }
        }
        if (count % 2 == 0) {
            return str.length();
        } else {
            if (str.charAt(0) == 'o') {
                return str.length() + 1;
            } else {
                return str.length() - 1;
            }
        }
    }

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

15.字符串变换最小字符串

给定⼀个字符串 s ,最多只能进⾏⼀次变换,返回变换后能得到的最⼩字符串(按照字典序进⾏⽐较)。
变换规则:交换字符串中任意两个不同位置的字符。
输⼊描述 :
        ⼀串⼩写字⺟组成的字符串s
输出描述 :
        按照要求进⾏变换得到的最⼩字符串
示例 1
输⼊
        abcdef
输出
        abcdef
示例 2
输⼊
        bcdefa
输出
        acdefb
    public static void getMinStr(char[] str) {
        char minChar = str[0];
        int minIndex = -1;
        for (int i = 0; i < str.length; i++) {
            for (int j = i + 1; j < str.length; j++) {
                if (str[j] < str[i]) {
                    if (str[j] <= minChar) {
                        minChar = str[j];
                        minIndex = j;
                    }
                }
            }
            if (minIndex != -1) {
                System.out.println(str[i] + "编号:" + i + ", " + minChar + "编号:" + minIndex);
                char temp = str[i];
                str[i] = str[minIndex];
                str[minIndex] = temp;
                break;
            }
        }
        System.out.println(str);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str = sc.nextLine();
            getMinStr(str.toCharArray());
        }
    }

16.整数对最小和

题目描述: 给定两个整数数组 array1 array2 ,数组元素按升序排列。假设从 array1 array2 中分别取出一个元素可构成一对元素,现在需要取出 k 对元素,并对取出的所有元素求和,计算和的最小值 注意:两对元素如果对应于 array1 array2 中的两个下标均相同,则视为同一对元素。
输入描述:
        输入两行数组 array1 array2
        每行首个数字为数组大小 size(0 < size <= 100);
        0 < array1[i] <= 1000 0 < array2[i] <= 1000
        接下来一行为正整数 k
        0 < k <= array1.size() * array2.size()
输出描述:
        满足要求的最小和
示例 1
输入 :
        3 1 1 2
        3 1 2 3
        2
输出 :
        4
    public static void getMinSum(int[] arr1, int[] arr2, int k) {
        List<Integer> list = new ArrayList<>();
        //    列举出所有元素对的和
        for (int num1 : arr1) {
            for (int num2 : arr2) {
                list.add(num1 + num2);
            }
        }
        int sum = 0;
        Collections.sort(list);
        for (int i = 0; i < k; i++) {
            sum += list.get(i);
        }
        System.out.println(sum);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int size1 = sc.nextInt();
            int[] arr1 = new int[size1];
            for (int i = 0; i < size1; i++) {
                arr1[i] = sc.nextInt();
            }

            int size2 = sc.nextInt();
            int[] arr2 = new int[size2];
            for (int i = 0; i < size2; i++) {
                arr2[i] = sc.nextInt();
            }
            int k = sc.nextInt();
            getMinSum(arr1, arr2, k);
        }
    }

17.幻方修复

【幻方修复】矩阵(Magic Square)是一个由1-共个整数构成的N*N矩阵,满足每行、列和对角线上的数字和都相等。老师在上课的时候讲了幻方的概念与例子,好学的小明将它们抄写在了小本本上,但是不小心抄错一个数字,你可以帮小明把这一个抄错的数字找出来并且改正吗?

输入描述:
第一行输入一个整数N,代表待检验幻方德阶数(3<=N<50)
接下来的N行,每行N个整数,空格隔开(0<=每个整数<=)
输出描述:
输出空格隔开的三个整数,分别是:出错行号、出错列号、应填入的数字(末尾无空格)

示例1
输入
3
8 1 6
3 5 7
4 0 2
输出 
3 2 9
    public static void findErrorNum(int[][] square, int N, int correctSum) {
        int errRow = 0, errCol = 0;
        int errorSum = 0;
        for (int i = 0; i < N; i++) {
            int sum = 0;
            for (int j = 0; j < N; j++) {
                sum += square[i][j];
            }
            if (sum != correctSum) {
                errRow = i + 1;
                errorSum = sum;
                break;
            }
        }
        for (int i = 0; i < N; i++) {
            int sum = 0;
            for (int j = 0; j < N; j++) {
                sum += square[j][i];
            }
            if (sum != correctSum) {
                errCol = i + 1;
                break;
            }
        }
        int correctNum = correctSum - errorSum + square[errRow - 1][errCol - 1];

        System.out.println(errRow + " " + errCol + " " + correctNum);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int N = sc.nextInt();
            //   根据幻方特性计算出每行每列以及对角线的和
            int correctSum = (1 + N * N) * N / 2;
            int[][] square = new int[N][N];
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    square[i][j] = sc.nextInt();
                }
            }
            findErrorNum(square, N, correctSum);
        }
    }

18.正则表达式替换

为了便于业务交互,约定一个对输入的字符串中的下划线做统一替换
具体要求L对于给定的输入字符串,将其中包含的每一个下划线"_",使用特殊字符串"(^|$|[,+])"替换,并输出替换后的结果
其中的例外场景不做替换,场景如下:
1.在一堆方括号之内的下划线则不替换
2.为转义的下划线,即"\_"则不替换
备注:
​​​​​​​1.调用者已经保证,输入表达式的方括号回承兑出现,并且方括号会存在嵌套。即存在"[xx[yyyy]xxx]"这种形式的字符串
2.输入字符串的长度范围:[0, 10000]
示例1
输入
"^(_9494)"
输出
"^((^|$|[,+])9494)"
    public static void replaceStr(char[] str) {
        System.out.println(str);
        int count = 0;
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < str.length; i++) {
            if (str[i] == '[') {
                count++;
            } else if (str[i] == ']') {
                count--;
            }
            if (count == 0) {
                if (str[i] == '_' && (i == 0 || str[i - 1] != '\\')) {
                    stringBuilder.append("(^|$|[,+])");
                } else {
                    stringBuilder.append(str[i]);
                }
            } else {
                stringBuilder.append(str[i]);
            }
        }
        System.out.println(stringBuilder);

    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str = sc.nextLine();
            replaceStr(str.toCharArray());
        }
    }

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值