每日一题 leetcode1734.解码异或后的排列

题:
在这里插入图片描述

码+思:

public int[] decode_overTime(int[] encoded) {
        // 使用前缀和的思想,使得encoded[i] = perm[0] ^ perm[i+1]
        // 因为已知答案唯一,所以第一个数的答案只能是1到n中的一个数,因此暴力解法,直到找到合适的第一个数为止
        for(int i = 1 ; i < encoded.length ; i++){
            encoded[i] = encoded[i-1]^encoded[i];
        }
        // 因为encoded[i] = perm[0] ^ perm[i+1],所以 perm[i+1] = encoded[i] ^ perm[0]
        // 固定perm[0]以后,求解其他的数,并加入到set中,如果出现重复数字,说明这个perm[0]不行 
        // 如果计算的perm[i+1]小于1或者大于perm.length 也不行
        // --------超出时间限制-------
        
        Set set = new HashSet<>();
        int[] ans = null;
        for(int i = 1 ; i < encoded.length+2 ; i++){
            int[] perm = new int[encoded.length+1]; 
            perm[0] = i;
            set.add(i);
            int j;
            for(j = 1 ; j < perm.length ; j++){
                perm[j] = perm[0] ^ encoded[j-1];
                if(set.contains(perm[j])||perm[j]>perm.length||perm[j]<1){
                    set.clear(); // 清空set
                    break;
                }
            }
            if(j == perm.length){
                ans = perm;
                break;
            }

        }
        return ans;
    }

结果:超出时间限制

优化后的码+思:

public int[] decode(int[] encoded){
        /*
            优化思路:
            现在是暴力解法,找到一个合适的perm[0] 使得题目所要求成立,但实际上,perm[0]可以直接求得
            因为对于原始的encoded而言,encoded[1]^encoded[3]^...^encoded[n-2] = perm[1]^perm[2]^perm[3]^...^perm[n-1] 
            n为奇数!所以n-2必为奇数
            假设处理后的Sum(term[0~n-1])为total
            则total = perm[0]^perm[1]^perm[2]^perm[3]^...^perm[n-1] = perm[0] ^ encoded[1]^encoded[3]^...^encoded[n-2]
            于是有perm[0] = total ^ encoded[1]^encoded[3]^...^encoded[n-2]
            而事实上 total是已经给定的,即total == 1 ^ 2 ^...^ n
        */
        int n = encoded.length+1;
        int total = 1;
        for(int i = 2 ; i <= n ; i++){
            total ^= i;
        }
        int[] perm = new int[n];
        perm[0] = total;
        for(int i = 1;i<=n-2;i+=2){
            perm[0] ^= encoded[i];
        }
        // 求encoded前缀和
        for(int i = 1 ; i < encoded.length ; i++){
            encoded[i] = encoded[i-1]^encoded[i];
        }
        // 求perm所有值
        for(int i = 1 ; i < n ; i++){
            perm[i] = encoded[i-1] ^ perm[0];
        }
        return perm;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值