标签:状态 面试题 维生物 题目 String int current 理解 规则
目录
朋友遇到的题目,分享一波。侵删~
这个题目的难点就在于读题,如果题目读明白了,问题自然就解决了。所以在看题的时候要耐心,需要发现除文字描述以外的信息。题目如下
题目
想象一种一维生物,由一系列顺序排列的细胞构成(可以理解为一维数组),细胞只有两种状态:活跃或者休眠(取值1或者0)。每经过一代进化,细胞状态都会发生改变。细胞进化后状态由当前该细胞状态和左右相邻细胞的状态决定。三个细胞最多有2×2×2=2^3=8种状态,在这8种状态下进化后的结果代表一种规则。例如:
上面这类规则表示当前细胞状态为休眠且相邻细胞状态为休眠时(000),当前细胞进化后状态为休眠(0);当前细胞休眠,左邻居休眠,右邻居活跃时(001),进化后状态为活跃(1);……;当前细胞活跃,左右邻居都活跃(111),进化后为休眠(0).
用8个bit表示的十进制数为规则编号,总共有0-255共256个规则,例如:
请写个程序,输出给定规则编号N下,该生物前K轮的进化状态。(假设生物的初始状态固定,且只有最中间一个细胞为活跃)
class Solution {
public List<String> printStates(int N, int K) {
}
}
例:
30号规则的进化过程如图所示。
还请读到这里的亲自己先尝试理解题目,去尽量多的收集规律和信息。
题目解读
想要看懂这个题目的重点就在于题目和样例中给的三幅图。首先看第一幅
从图片和题目的描述我们可以知道,每一个方框内有四个小格子(状态位),黑色代表该位是1,白色代表该位是0;上排三个连续的格子为当前状态位,表示当前自己和前后邻居当前状态,下边单独的格子为衍生位,表示在当前状态位是某个值的时候,下一次自己衍生出来是0还是1。
第二幅图给出了几个规则关系。
每一个rule代表了一种衍生关系,从读题的感觉来看,我们需要在这幅图中找到规律来知道rule0 ~ rule126的排列关系。自己观察后,确实发现了规律:
给出的所有rule中,当前状态位的排列都是固定的,都是「“111”,“110”,“101”,“100”,“011”,“010”,“001”,“000”」,而规则编号比如rule30,刚好是将八个格子看成是八个bit后,对应位 置1后得到30,00011110 = 2+4+8+16 = 30;其他规则也同样遵循这个规律。那可想而知,rule0就是00000000,rule1就是00000001,以此类推。
解题
读题到这里,就可以开始构思解题思路了。主要分两步:1- 构建规则映射; 2- 循环进化得到结果。
题目中描述会给定两个int值,n代表规则num,k代表迭代轮数。那么首先我们要通过n构建出一个代表规则的字典,然后让给定的初始数组按照规则字典进化。
因为key是固定的「“111”,“110”,“101”,“100”,“011”,“010”,“001”,“000”」,规则字典只需要找到n对应的那几位为1即可。代码如下:
public static Map<String,String> generateRule(int n){
//按照从最低位到最高位的顺序排列
String [] values = new String[] {"000","001","010","011","100","101","110","111"};
Map<String,String > rule = new HashMap<>();
for (int i = 0;i < 8;i++){
if ((n & (1 << i)) == 0){
rule.put(values[i],"0");
}else {
rule.put(values[i],"1");
}
}
return rule;
}
一共八位所以循环八次,用1左移0位同n做与运算,如果得到是0,则n的第0位是0,如果结果大于0,则该位为1.
得到规则映射后,进入进化阶段:
public static List<String> printStates(int n,int k){
List<String> result = new ArrayList<>();
Map<String,String> rule = generateRule(n);
String [] current = new String[31];
String [] help = new String[31];
//set default values
for (int i = 0; i < current.length; i++){
if (i == 15){
current[i] = "1";
}else {
current[i] = "0";
}
}
result.add(Solution.toString(current));
String varifyValue = "";
for (int j = 0; j < k;j++){
for (int i = 0; i < current.length; i++){
if (i == 0){
varifyValue = current[current.length - 1] + current[0] + current[i + 1];
}else if (i == current.length - 1){
varifyValue = current[i - 1]+ current[i] + current[0];
}
else {
varifyValue = current[i - 1] + current[i] + current[i + 1];
}
help[i] = rule.get(varifyValue);
}
current = help.clone();
result.add(Solution.toString(help));
}
return result;
}
public static String toString(String [] strs){
String res = "";
for (String s : strs){
res += s;
}
return res;
}
进化阶段需要注意的就是边界值了,从样例图中可以看到,第一个一维生物的进化是以最后一个单位作为左邻居的,而最后一个一维生物是以第一个单位作为右邻居的(请回看题目样例中的规则和衍生结果),除了这两种情况以为,每次的key等于前中后的组合值作为key去rule map中取值即可。每次迭代的结果存放到List中等待返回。
最终代码运行结果截图和样例对比如下
跟同事聊的过程中同事点拨,当前状态位中的「“111”,“110”,“101”,“100”,“011”,“010”,“001”,“000”」就是7 ~ 0的二进制排列。
这道题目的实现难度可以说几乎没有,但是在面试的紧张状态下很好的理解题目,从给出的信息中挖掘文字描述之外的信息,这方面考的很好了。
标签:状态,面试题,维生物,题目,String,int,current,理解,规则 来源: https://blog.csdn.net/weixin_39445556/article/details/106851315
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。