因为我即将进行技术面试,我最近开始研究“破解编码面试”一书。
当我练习5.1的问题时,我发现这本书的解决方案与我的不同。
问题是:
您将获得两个32位数字,N和M,以及两个位,即i和j。 编写一种方法来将N和j之间的所有位设置为N等于M(例如,M变为位于i的N的子串并从j开始)。 实施例:
Input: N = 10000000000, M = 10101, i = 2, j = 6
Output: N = 10001010100
解决方案是:
public static int updateBits2(int n, int m, int i, int j) {
int max = ~0;
int left = max - ((1 << j) - 1);
int right = (1 << i) - 1;
int mask = left | right;
int maskN = mask & n;
int result = maskN | (m << i);
return result;
}
关键是要创建一个掩码来将i的位设置为n到0的j, 并且左移m到i位置和OR m和n。
当输入为n = 89,m = 3,i = 2,j = 4时,答案应为77,对于:
n = 1011001
m = 011
n with 2 to 4 set by m = 1001101 = 77
但解决方案的结果是93。
然后我发现解决方案创建的掩码缺少一个0位 在左侧。 例如,掩码应为1100011,上面给定输入。 但是解决方案创建的掩码是1110011。
我通过改变这一行来解决这个问题
int left = max - ((1 << j) - 1);
到
int left = max - ((1 << j + 1) - 1);
所以我的问题是,解决方案是错误的还是我错过了什么?
答案 0 :(得分:0)
你可以通过例子来判断,其中i = 2,j = 6,并且改变了5位,[i,j]意味着包含范围。因此,如果你有i = 2和j = 4,你应该设置3位,而不是2位。
因此,您发布的功能(我无法判断您的功能或引用的功能)是否为updateBits2
不正确。
但是,在j==31
时,您的修复失败,这是他们在编码面试中会引起您的错误。使用(1<<(j+1))-1
代替(1<<j)|((1<<j)-1)
,或将整行缩短为left = -2<<j;
答案 1 :(得分:0)
我遇到了同样的问题。我认为解决方案是错误的。
int left = max - ((1 << j) - 1);
应更改为:
int left = max - ((1 << j + 1) - 1);