2021.1.14每日复习 89.格雷编码(多种方法)+ 90.子集2(DFS+去重)

89.格雷编码(多种方法)

在这里插入图片描述

class Solution {
    public List<Integer> grayCode(int n) {
    	//镜面反射法
        List<Integer> res = new ArrayList<>();
        res.add(0);
        int head = 1;
        for(int i = 0; i < n; i++) {
            for(int j = res.size() - 1; j >= 0; j--) {
                res.add(head + res.get(j));
            }
            head <<= 1;
        }
        return res;

		//直接推导法
		List<Integer> gray = new ArrayList<Integer>();
    	gray.add(0); //初始化第零项
    	for (int i = 1; i < 1 << n; i++) {
        	//得到上一个的值
        	int previous = gray.get(i - 1);
        	//同第一项的情况
        	if (i % 2 == 1) {
            	previous ^= 1; //和 0000001 做异或,使得最右边一位取反
            	gray.add(previous);
        	//同第二项的情况
        	} else {
            	int temp = previous;
            	//寻找右边起第第一个为 1 的位元
            	for (int j = 0; j < n; j++) {
                	if ((temp & 1) == 1) {
                   	 //和 00001000000 类似这样的数做异或,使得相应位取反
                    	previous = previous ^ (1 << (j + 1));
                  	  gray.add(previous);
                  	  break;
          	      }
        	        temp = temp >> 1;
         	   }
     	   }
		}
  	  	return gray;
    }
}


90.子集2(DFS+去重)

在这里插入图片描述

class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        if(nums.length < 1) return res;
        Deque<Integer> path = new ArrayDeque<>();
        Arrays.sort(nums);
        dfs(nums, 0, path, res);
        return res;
    }
    public void dfs(int[] nums, int start, Deque<Integer> path, List<List<Integer>> res) {
        res.add(new ArrayList<>(path));
        for(int i = start; i < nums.length; i++) {
            //这是判断同层分支节点不能有相同的值
            if(i > start && nums[i] == nums[i - 1]) continue;
            //if(i > 0 && nums[i] == nums[i - 1]) continue; //这样判断,把子节点和父节点相同的情况也会删去,这样是不对的,不同层元素允许相同
            path.addLast(nums[i]);
            dfs(nums, i + 1, path, res);
            path.removeLast();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值