力扣779、第K个语法符号---GOGOGO

记录下自己第一次完全实现迭代,明天继续做几道,先记录下

在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为011替换为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));;

	}

}
发布了48 篇原创文章 · 获赞 9 · 访问量 2404

猜你喜欢

转载自blog.csdn.net/jjy19971023/article/details/104645835