leetcode gray-code

题目描述

The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
For example, given n = 2, return[0,1,3,2]. Its gray code sequence is:
00 - 0
01 - 1
11 - 3
10 - 2

Note:

For a given n, a gray code sequence is not uniquely defined.
For example,[0,2,3,1]is also a valid gray code sequence according to the above definition.
For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.

package BrushProblem.leetcode;

import java.util.ArrayList;

/**
 * @Auther: 李景然
 * @Date: 2018/10/8 08:34
 * @Description: gray-code
 */
public class GrayCode {
    public static void main(String[] args) {
        GrayCode grayCode=new GrayCode();
        ArrayList<Integer> result=grayCode.grayCode3(2);
        int size=result.size();
    }

    /*
    *规律是,后面每一个list的元素等于前面list顺序遍历的结果在每个元素前面+“0”,再逆序遍历
    *每个元素前面+"1",可以先存储string格式方便处理,最后转换再返回int的集合
    *就可以用动态规划解决了。
    *
        当n=1时,为[0,1]
        当n=2时,为[00,01,11,10]
        当n=3时,为[000,001,011,010,110,111,101,100]
        由此可以看出新的序列其实是在前面序列基础上插入新的值
        其中前半部分的数值不变,后半部分的数值为上个序列中每个元素第n个位变1,逆向插入
    */
    public ArrayList<Integer> grayCode(int n) {
        ArrayList<Integer> result = new ArrayList<>();
        ArrayList<String> pre = new ArrayList<>();

        if (n == 0) {
            result.add(0);
            return result;
        }
        pre.add("0");
        pre.add("1");
        for (int i=2;i<=n;i++){
            ArrayList<String> now = new ArrayList<>();
            for (int m=0;m<pre.size();m++){
                now.add("0"+pre.get(m));
            }
            for (int m=pre.size()-1;m>=0;m--){
                now.add("1"+pre.get(m));
            }
            pre=now;
        }
        for (int i=0;i<pre.size();i++){
            result.add(getNum(pre.get(i)));
        }
        return result;
    }

    private Integer getNum(String s) {
        int result=0;
        int i=0;
        while (i<s.length()){
            if(s.charAt(i)=='1'){
                result+=Math.pow(2,s.length()-1-i);
            }
            i++;
        }
        return result;
    }

    /*
    * (i-1)<<1表示i-1向左移动1位
    * 1<<(i-1)表示1向左移动i-1位
    * a<<b表示a向左移动b位
    * a>>b表示a向右移动b位
    * */
    public ArrayList<Integer> grayCode2(int n) {
        ArrayList<Integer> result=new ArrayList<>();
        if(n==0){
            result.add(0);
            return result;
        }

        result.add(0);
        result.add(1);
        for (int i=2;i<=n;i++){
            for (int j=result.size()-1;j>=0;j--){
                result.add(result.get(j)+(1<<(i-1)));
            }
        }
        return result;
    }

    //巧妙的方法
    public ArrayList<Integer> grayCode3(int n) {
        ArrayList<Integer> ans = new ArrayList<Integer>();
        int length = 1 << n;//1 << n 等于 Math.pow(2,n)
        for(int i=0; i<Math.pow(2,n); i++){
            int num=(i>>1)^i;
            ans.add(num);
        }
        return ans;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值