领导让我脱离ai写代码,我纯手工写了,领导说我拉了一坨大的。。
刚看到个贴子,说一个程序员被领导要求“脱离AI手写代码”,结果他真的纯手工写了,领导看完骂他“拉了一坨大的”。这贴子一出,网友炸了,有的说领导自相矛盾,有的说这哥们太老实。
我觉得这事吧,本质不是AI和人工的对立,而是“成果导向”的问题。领导要你脱离AI,可能是想看你有没有独立思考能力,不是真的要你拒绝工具。结果你真“手写”了,他反而觉得你不懂效率。听着荒唐,其实很典型——职场上很多任务都是“揣摩上意”的考题。
网友们骂领导双标也有道理,但反过来想,咱打工人也得懂规则:用不用AI不是重点,能不能写出好代码、解决问题才是底线。说到底,工具只是刀,关键还得看谁拿着。【备注:文末可领最新资料】
算法题:单词游戏
想象一下你和同桌在玩一个小游戏: 桌上有一堆英文单词,全是小写,比如:ab、bc、cd、da。
规则是这样的: 前一个单词的最后一个字母,要等于下一个单词的第一个字母,而且——
每个单词必须用一次、只能用一次 最后一个单词的结尾字母,还得能接回第一个单词的开头字母,形成一个环
问题就变成了: 给你 N 个单词,能不能把它们排成这样一个圈? 这就是经典的“单词游戏”算法题。
怎么抽象成图论问题?
这种题如果直接在字符串上硬拼,基本会被绕晕。换个角度想,会简单很多。
我们可以把 每个字母 看成一个点(顶点),一共 26 个:a ~ z。 然后把 每个单词 看成一条从「首字母」到「尾字母」的有向边。
举个例子:
单词 ab:就是从a指向b的一条边单词 bc:就是从b指向c的一条边
这样一来,题目就变成一句很“图论”的话:
给定一张有向图,每条边表示一个单词,能不能用所有边恰好走一遍,并且走成一个回路?
这在图论里有一个专门的名字:有向图的欧拉回路(Eulerian Circuit)。
欧拉回路的两个关键条件
对于一张有向图,要想存在包含所有边的欧拉回路,需要满足两个核心条件:
每个点的入度 = 出度
出度:以这个点为起点的边的条数 入度:以这个点为终点的边的条数 对应到我们的题目,就是: 某个字母开头的单词有多少个,它结尾的单词也得有多少个,否则“接不平”。
所有“出现过的点”在忽略方向后是连通的简单说就是: 把边当成无向边来看的时候,所有参与过单词的字母,必须都在同一个连通块里。 否则就会出现“两坨不相干的字母群”,那肯定不可能把所有单词串成一个圈。
所以算法思路就很明确了:
用 26 个点建图 统计每个点的入度、出度 用 DFS / BFS 检查连通性 度数 & 连通性条件都满足,就能构成“单词游戏”的闭环
具体算法步骤(用人话串一遍)
大概流程如下:
准备几个数组:
in[26]:记录每个字母的入度out[26]:记录每个字母的出度adj:无向邻接表,用来做连通性检查(把有向边当成无向边加入)
遍历每个单词 w:
u = w.charAt(0) - 'a'作为起点v = w.charAt(w.length()-1) - 'a'作为终点out[u]++,in[v]++在无向图里加边: u <-> v
检查入度和出度:
对于每个字母 i:如果in[i] != out[i],那就直接判定 不可能成环
检查连通性:
找一个“度数 > 0” 的起点 start从 start做一次 DFS / BFS(用无向图)把所有“度数 > 0 的点”都数一下,看是否都被访问到了 如果有某个参与过单词的字母没有被访问到,也是不行的
如果以上两个检查都通过,那么答案就是:可以完成这个单词游戏。
下面给一份相对简洁的 Java 写法,核心就是上面那套逻辑:
import java.util.*;
publicclassWordGame{
// 判断是否能把所有单词排成一个首尾相接的圈
publicstaticbooleancanFormCircle(List<String> words){
int[] in = newint[26];
int[] out = newint[26];
List<Integer>[] adj = new ArrayList[26];
for (int i = 0; i < 26; i++) {
adj[i] = new ArrayList<>();
}
// 记录哪些字母真正出现过
boolean[] used = newboolean[26];
for (String w : words) {
if (w == null || w.length() == 0) continue;
char first = w.charAt(0);
char last = w.charAt(w.length() - 1);
int u = first - 'a';
int v = last - 'a';
out[u]++;
in[v]++;
used[u] = used[v] = true;
// 无向图,用于连通性检查
adj[u].add(v);
adj[v].add(u);
}
// 条件一:入度 = 出度
for (int i = 0; i < 26; i++) {
if (in[i] != out[i]) {
returnfalse;
}
}
// 找一个度数 > 0 的点作为 DFS 起点
int start = -1;
for (int i = 0; i < 26; i++) {
if (in[i] + out[i] > 0) {
start = i;
break;
}
}
// 没有任何单词,其实可以认为既成环又没意义,这里按“无法形成”处理
if (start == -1) returnfalse;
// 条件二:忽略方向后,所有出现过的点必须连通
boolean[] visited = newboolean[26];
dfs(start, adj, visited);
for (int i = 0; i < 26; i++) {
if (used[i] && !visited[i]) {
returnfalse;
}
}
returntrue;
}
privatestaticvoiddfs(int u, List<Integer>[] adj, boolean[] visited){
visited[u] = true;
for (int v : adj[u]) {
if (!visited[v]) {
dfs(v, adj, visited);
}
}
}
// 随便写个 main 简单测一下
publicstaticvoidmain(String[] args){
List<String> words1 = Arrays.asList("ab", "bc", "cd", "da");
System.out.println(canFormCircle(words1)); // true
List<String> words2 = Arrays.asList("ab", "bc", "ca", "ad");
System.out.println(canFormCircle(words2)); // false
}
}
你在刷题平台上做这道“单词游戏”的题时,大多数输入输出格式都会不太一样(有的多组用例,有的是从标准输入读),但核心判断逻辑基本就是这套:欧拉回路 = 入度出度相等 + 连通性 OK。
剩下的,就是把这坨逻辑根据题目的输入格式,稍微包一包就能 AC 了。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html