刷题题解-3 | 豆包MarsCode AI刷题

36 阅读4分钟

找出整形数组中占比超过一半的数

1. 问题描述

小R从班级中抽取了一些同学,每位同学都会给出一个数字。已知在这些数字中,某个数字的出现次数超过了数字总数的一半。现在需要你帮助小R找到这个数字。

2. 测试样例

样例1:

输入:array = [1, 3, 8, 2, 3, 1, 3, 3, 3]
输出:3

样例2:

输入:array = [5, 5, 5, 1, 2, 5, 5]
输出:5

样例3:

输入:array = [9, 9, 9, 9, 8, 9, 8, 8]
输出:9

3. 思路

假设在一个有序的数组A中,存在一个数xxxx的数量超过整个数组长度的一半,那么有以下三种可能:

  • aia_i在前一半:
x,x,...,x,xai,...,anx,x,...,x,x|a_{i},...,a_{n}
  • aia_i在后一半:
a0,...,aix,x,x...,xa_{0},...,a_{i} | x,x,x...,x
  • aia_i在前后一半都有:
a0,...,x,x,xx,x,x,...,ana_{0},...,x, x, x | x,x,x,...,a_{n}

可以看出,无论那种情况,xx一定在有序数组的中间位置,因此只需要对数组排序,输出n/2处的值,就是需要找到的数。

4. 代码

import java.util.Arrays;

public class Main {
    public static int solution(int[] array) {
        Arrays.sort(array);
        int len = array.length;
        return array[len/2];
    }

    public static void main(String[] args) {
        System.out.println(solution(new int[]{1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3);
    }
}

字符串最短循环子串

1. 问题描述

小M在研究字符串时发现了一个有趣的现象:某些字符串是由一个较短的子串反复拼接而成的。如果能够找到这个最短的子串,便可以很好地还原字符串的结构。你的任务是给定一个字符串,判断它是否是由某个子串反复拼接而成的。如果是,输出该最短的子串;否则,输出空字符串""

例如:当输入字符串为 abababab 时,它可以由子串 ab 反复拼接而成,因此输出 ab;而如果输入 ab,则该字符串不能通过子串的重复拼接得到,因此输出空字符串。

2. 测试样例

样例1:

输入:inp = "abcabcabcabc"
输出:'abc'

样例2:

输入:inp = "aaa"
输出:'a'

样例3:

输入:inp = "abababab"
输出:'ab'

3. 思路

假设字符串S是由n个字符串T重复而来,那么可以得出以下结论:

  • n = S.length / T.length
  • 字符串T一定是S从下标0开始的一个子串;

那么我们可以如下操作:

  • 从下标0开始枚举T的长度,判断N个T拼接后的字符串能不能与S一致;
  • 如果一致则说明找到了T,否则说明不是;
  • 枚举到S的一半长度还没有找到说明没有字符串T。

4. 代码

public class Main {
    public static String solution(String inp) {
        int inpL = inp.length();
        if(inpL < 2) return "";

        for(int i=1; i<=inpL/2; i++){
            String s = inp.substring(0, i);
            if(inpL % i == 0){
                int ans = inpL / i;
                String tmp = "";
                for(int j=0; j<ans; j++){
                    tmp += s;    
                }
    
                if(tmp.equals(inp)) return s;
            }
           
        }

        return "";
    }

    public static void main(String[] args) {
        System.out.println(solution("abcabcabcabc").equals("abc"));
    }
}

蛇形填充N阶方阵

1. 问题描述

小U面临一个有趣的任务:在一个 n×nn×n 的方阵中填入 11 到 n×nn×n 这些数字,并要求按照蛇形顺序从右上角开始,沿着方阵的边界顺时针进行填充。蛇形填充的特殊排列方式使得每一层数字呈现出波浪形的排列方式。

例如,当 n=4n=4 时,方阵应如下所示:

10 11 12  1
9 16 13  2
8 15 14  3
7  6  5  4

2. 测试样例

样例1:

输入:n = 4
输出:[[10, 11, 12, 1], [9, 16, 13, 2], [8, 15, 14, 3], [7, 6, 5, 4]]

样例2:

输入:n = 5
输出:[[13, 14, 15, 16, 1], [12, 23, 24, 17, 2], [11, 22, 25, 18, 3], [10, 21, 20, 19, 4], [9, 8, 7, 6, 5]]

样例3:

输入:n = 3
输出:[[7, 8, 1], [6, 9, 2], [5, 4, 3]]

3. 思路

通过偏移向量来达到蛇形的目的,每次更新位置后查看是否越界,如果越界那么就改变一下方向,直至填充完毕。

4. 代码

import java.util.Arrays;

public class Main {
    public static int[][] solution(int n) {
        int[] dx = { 1, 0, -1, 0 };
        int[] dy = { 0, -1, 0, 1 };

        int[][] res = new int[n][n];
        for (int i = 0; i < n; i++)
            Arrays.fill(res[i], 0);
        int x = 0, y = n - 1, idx = 0;

        for (int i = 1; i <= n*n; i++) {
            res[x][y] = i;
            int a = x + dx[idx];
            int b = y + dy[idx];
            if (a < 0 || a >= n || b < 0 || b >= n || res[a][b] != 0) {
                idx = (idx + 1) % 4;
                a = x + dx[idx];
                b = y + dy[idx];
            }
            x = a;
            y = b;
        }

        return res;
    }

    public static void main(String[] args) {
        int[][] a1 = solution(4);
        System.out.println(java.util.Arrays.deepEquals(a1,new int[][] { { 10, 11, 12, 1 }, { 9, 16, 13, 2 }, { 8, 15, 14, 3 }, { 7, 6, 5, 4 } }));
    }
}