记录下自己第一次完全实现迭代,明天继续做几道,先记录下
在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。
给定行数 N 和序数 K,返回第 N 行中第 K个字符。(K从1开始)
例子:
输入: N = 1, K = 1 输出: 0
输入: N = 2, K = 1 输出: 0
输入: N = 2, K = 2 输出: 1
输入: N = 4, K = 5 输出: 1
解释:第一行: 0 第二行: 01 第三行: 0110 第四行: 01101001
注意: N 的范围 [1, 30]. K 的范围 [1, 2^(N-1)].
这个迭代的难点就在找规律
发现规律。
规律规律
你在哪啊????
A???
我们看下第四行
01101001 这个的前4个是不是很熟悉?对就是第三个。
那么接下来我们写下第五行
110100110010110. 对没错前面8个还是重复的为第四个
欧克欧克,接下来开始find规律
规律一、我们每个下一行的前半行都是上一行的重复
这也就有了一条判断。当传入的K值小于2的N-2次方的时候,也就是小于一半的时候,直接可以迭代到下一步,K值不变
当K值大于当前长度的一半以上的时候,我们来寻找K的规律
从第三行开始我们4个一组的去看。
第三行 | 0 | 1 | 1 | 0 |
---|---|---|---|---|
第四行 | 01 | 10 | 10 | 01 |
我观察下他们的下标,第四行的最后四个的下标,和第三行的最后两个进行对比
OK这样我们的算法也就清晰啦。
基础情况是当N等于2时
特殊情况是N等于1时
对应算法二,算法一蛮力法,出力不讨好。不细说了,大家随意看看吧
public class Grammer {
public int kthGrammar(int N, int K) {
if(N==1)
return 0;
String s="0";
s=findN(N,s);
System.out.println(s);
return new Integer(s.substring(K-1, K));
}
private String findN(int n,String s) {
// TODO 自动生成的方法存根
StringBuilder temp=new StringBuilder(s);
for(int i=0;i<temp.length();i++){
if(temp.charAt(i)=='0')
{
temp.replace(i, i+1, "01");
i++;
}else{
temp.replace(i, i+1, "10");
i++;
}
}
n=n-1;
if(n==1)
return temp.toString();
else
return findN(n,temp.toString());
}
public int kthGrammar2(int N, int K) {
if(N==1)
return 0;
if(N==2)
return K==1?0:1;
int num =(int) Math.pow(2, N-2);
if(K>num)
{
if(K%4==0)
return kthGrammar2(N-1,K/2-1);
else
return kthGrammar2(N-1,K/2+1);
}
else
return kthGrammar2(N-1,K);
}
public static void main(String[] args) {
Grammer g=new Grammer();
System.out.println(g.kthGrammar(1, 1));;
}
}