小美的字符串变换(美团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);
}
}

浙公网安备 33010602011771号