小美的字符串变换(美团2024届秋招笔试第一场编程真题)

题面

核心思想

这题主要在于复杂度的考虑
枚举每一行能放多少个并不是o(n)的
就算是10000也就20几个能整除的
所以第一层循环复杂度很小 内循环一遍dfs o(n)搜索就ok
这里也没有新建矩阵 是在原字符串上操作的~

代码

import java.util.*;

public class Main {

    public static void main(String[] args) {
        final long MOD = (long) (1e9 + 7);
        Scanner scanner = new Scanner(System.in);
        int n = Integer.parseInt(scanner.nextLine());
        int res = n;// 初始答案设为n个连通块
        String s = scanner.nextLine();
        int[] v = new int[n]; // 访问标记
        for(int i = 1; i < n; i++){
            // 表示每行放i个
            if(n % i == 0){
                Arrays.fill(v, 0); // 标记置0
                int cnt = 0;// 连通数
                for(int j = 0; j < s.length(); j++){
                    if(v[j] == 0){
                        cnt++; // 连通数+1
                        dfs(j, i, n, v, s);// j开始寻找 每行放i个
                    }
                }
                res = Math.min(res, cnt);
            }
        }
        System.out.println(res);
    }

    private static void dfs(int cur, int numOfRow, int n, int[] v, String s){
        if(v[cur] == 1)
            return;;
        v[cur] = 1;
        int row = cur / numOfRow; //所在行数
        int startCol = numOfRow * row; // 行起始列(包含)
        int endCol = startCol + numOfRow;// 行结束列(不包含)
        // 上走
        if(cur - numOfRow >=0 && s.charAt(cur - numOfRow) == s.charAt(cur))
            dfs(cur - numOfRow, numOfRow, n, v, s);

        // 右走
        if(cur + 1 < n && cur + 1 < endCol && s.charAt(cur + 1) == s.charAt(cur))
            dfs(cur + 1, numOfRow, n, v, s);

        //下走
        if(cur + numOfRow < n && s.charAt(cur + numOfRow) == s.charAt(cur))
            dfs(cur + numOfRow, numOfRow, n, v, s);

        //左走
        if(cur - 1 >=0 && cur - 1 >= startCol && s.charAt(cur - 1) == s.charAt(cur))
            dfs(cur - 1, numOfRow, n, v, s);
    }
}
posted @ 2024-04-07 14:20  Shie1d  阅读(140)  评论(0)    收藏  举报