2021-05-11 力扣每日一题

1734解码异或后的排列

问题描述:

​ 给你一个整数数组 perm ,它是前 n 个正整数的排列,且 n 是个 奇数 。它被加密成另一个长度为 n - 1 的整数数组 encoded ,满足 encoded[i] = perm[i] XOR perm[i + 1] 。比方说,如果 perm = [1,3,2] ,那么 encoded = [2,1] 。给你 encoded 数组,请你返回原始数组 perm 。题目保证答案存在且唯一。

示例1:
输入:encoded = [3,1]
输出:[1,2,3]
解释:如果 perm = [1,2,3] ,那么 encoded = [1 XOR 2,2 XOR 3] = [3,1]
示例2:
输入:encoded = [6,5,4,6]
输出:[2,4,1,5,3]

思路:

  • 写过1720题的小伙伴应该懂这个问题应该怎么写,很明显,如果没有几个约束条件的话,我们可以得出n种不同的结果,但是要求perm是一个前n个正整数的排列,那么结果就只有一个了,那到底是哪一种排列呢?
  • 1720题地址

​ 根据上次的结论,如果a异或b = c,那么abc三个值任意两个的异或都等于第三个值。有了这个结论,我们就可以得知,如果确定了perm中的一个值,那么整个perm数组就可以确定下来。但是那一个值应该怎么确定呢?

​ 因为perm是一个从1到n的一个排列,所以perm中所有元素的异或我们是可以直接算出来的。也就是1 ^ 2 ^ 3 . . . ^ n,而如果我们能求出perm[ 1 ]^…perm[ n ]的话,我们就可以求出perm[ 0 ]的值,这样我们就可以确定perm中的第一个数字,进而可以求出perm中所有的数字。

​ 又因为 encoded[i] = perm[i] XOR perm[i + 1]这里的encoded[ i ]等于perm中两个数的异或,那么同样的,encoded[i+2] = perm[i+2] XOR perm[i+3]。这样的话,我们就可以通过encoded来求出perm[ 1 ]异或到perm[ n ]。也就解决了问题。

Java代码:

/**
* @Description: 力扣1734题题解
* @return: 返回结果
* @Author: Mr.Gao
* @Date: 2021/5/11
*/
public int[] decode2(int[] encoded){
    int n = encoded.length+1;
    int total = 0;
    for(int i=1;i<=n;i++){
        total^=i;
    }
    int odd = 0;
    for(int i=1;i<n-1;i+=2){
        odd^=encoded[i];
    }
    int[] perm = new int[n];
    perm[0] = total^odd;
    for (int i = 0; i < n-1; i++) {
        perm[i+1] = perm[i]^encoded[i];
    }
    return perm;
}
  • 这个是官方题解给的思路,而我的思路呢…就是暴力遍历从1到n,找到最合适的0号位置的值,不出意外,果然爆掉了。

错误的Java代码:

/**
* @Description: 力扣1734题题解
* @return: 返回结果
* @Author: Mr.Gao
* @Date: 2021/5/11
*/

public int[] decode(int[] encoded) {
    int n = encoded.length;
    int[] a = new int[n+1];
    for(int i=1;i<=n;i++){
        a[0] = i;
        int j=0;
        for (j = 0; j < n; j++) {
            a[j+1] = a[j]^encoded[j];
            if(a[j+1]>n+1||a[j+1]<0){
                break;
            }
        }
        if(j==n){
            return a;
        }
    }
    return null;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值