非常感謝你閱讀本文~
歡迎【👍點贊】【?收藏】【📝評論】~
放棄不難,但堅持一定很酷~
希望我們大家都能每天進步一點點~
本文由 二當家的白帽子 https://le-yi.blog.csdn.net/ 博客原創~
文章目錄
- 1486. 陣列異或操作:
- 樣例 1
- 樣例 2
- 樣例 3
- 樣例 4
- 提示
- 分析
- 題解
- java
- c
- c++
- python
- go
- rust
- 原題傳送門
1486. 陣列異或操作:
給你兩個整數,n 和 start ,
陣列 nums 定義為:nums[i] = start + 2 * i(下標從 0 開始)且 n == nums.length ,
請回傳 nums 中所有元素按位異或(XOR)后得到的結果,
樣例 1
輸入:
n = 5, start = 0
輸出:
8
解釋:
陣列 nums 為 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 ,
"^" 為按位異或 XOR 運算子,
樣例 2
輸入:
n = 4, start = 3
輸出:
8
解釋:
陣列 nums 為 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8.
樣例 3
輸入:
n = 1, start = 7
輸出:
7
樣例 4
輸入:
n = 10, start = 5
輸出:
2
提示
- 1 <= n <= 1000
- 0 <= start <= 1000
- n == nums.length
分析
我們可以直接按照題意,暴力回圈,那么時間復雜度就是O(n),是否有時間復雜度為O(1)的演算法呢?
記x為變數,^是異或操作,則異或運算滿足以下性質:
- x ^ x = 0;
- x ^ 0 = x;
- x ^ y = y ^ x(交換律);
- (x ^ y) ^ z = x ^ (y ^ z)(結合律);
- x ^ y ^ y = x(自反性);
- 如果x是4的倍數,x ^ (x + 1) ^ (x + 2) ^ (x + 3) = 0;
- 本題要計算的 結果公式 為:start ^ (start + 2) ^ (start + 4) ^ ? ^(start + 2 * (n ? 1)),
- 如果有一個函式 sumXor(x) 可以計算 0 ^ 1 ^ 2 ^ ? ^ x ,
- 對于某變數x和n,計算sumXor(s - 1) ^ sumXor(s + n - 1)的結果,根據上面的 性質1 可以將 0 ^ 1 ^ 2 ^ … ^ (s - 1) 的值抵消為0,就變成 0 ^ s ^ (s + 1) ^ (s + 2) ^ ? ^ (s + n - 1) ,根據 性質2 可知與0做異或操作還是自己,最后結果就變成 s ^ (s + 1) ^ (s + 2) ^ ? ^ (s + n - 1) ,這個結果很接近我們要計算的內容,
- 如果我們令 s = start / 2 ,把 結果公式 轉換成 (s ^ (s + 1) ^ (s + 2) ^ ? ^ (s + n - 1)) * 2,這樣并不成立,因為在做除以2的操作時,最低位丟失了,但是我們可以單獨處理最低位,
- 觀察 結果公式 可知 (start + 2),(start + 4) ,… ,(start + 2 * (n ? 1)) 的奇偶性質相同,而且和start一致,也就是最低位要么都是0,要么都是1,只有基數個1做異或操作時才會是1,也就是只有start是奇數并且n是奇數的時候,最終結果的最低位 e 才會是1,
- 這時 結果公式 可以轉化為: ((sumXor(s - 1) ^ sumXor(s + n - 1)) * 2) | e ,
只要我們可以實作函式sumXor(x),那么題目計算就可以做到O(1)的時間復雜度,根據 性質6 和 性質2 我們只需要考慮x除以4的余數,也就是最低2位,可以得到如下推導:
x % 4 = 0 的二進制位:xx…x00
x % 4 = 1 的二進制位:xx…x01
x % 4 = 2 的二進制位:xx…x10
x % 4 = 3 的二進制位:xx…x11
- x % 4 = 0,sumXor(x) = x;
- x % 4 = 1,sumXor(x) = (x - 1) ^ x,簡化可得 sumXor(x) = 1;
- x % 4 = 2,sumXor(x) = (x - 2) ^ (x - 1) ^ x,簡化可得 sumXor(x) = x | 1;
- x % 4 = 3,sumXor(x) = 0;
- x % 4 等同于 x & 3 的操作,而且理論上 & 操作要比 % 操作更快;
題解
java
class Solution {
public int xorOperation(int n, int start) {
int s = start >> 1, e = n & start & 1;
int ret = sumXor(s - 1) ^ sumXor(s + n - 1);
return ret << 1 | e;
}
public int sumXor(int x) {
switch (x & 3) {
case 0:
return x;
case 1:
return 1;
case 2:
return x | 1;
default:
// x & 3 == 3
return 0;
}
}
}
c
int xorOperation(int n, int start) {
int s = start >> 1, e = n & start & 1;
int ret = sumXor(s - 1) ^ sumXor(s + n - 1);
return ret << 1 | e;
}
int sumXor(int x) {
switch (x & 3) {
case 0:
return x;
case 1:
return 1;
case 2:
return x | 1;
default:
// x & 3 == 3
return 0;
}
}
c++
class Solution {
public:
int xorOperation(int n, int start) {
int s = start >> 1, e = n & start & 1;
int ret = sumXor(s - 1) ^ sumXor(s + n - 1);
return ret << 1 | e;
}
int sumXor(int x) {
switch (x & 3) {
case 0:
return x;
case 1:
return 1;
case 2:
return x | 1;
default:
// x & 3 == 3
return 0;
}
}
};
python
class Solution:
def xorOperation(self, n: int, start: int) -> int:
def sumXor(x):
if x % 4 == 0:
return x
if x % 4 == 1:
return 1
if x % 4 == 2:
return x | 1
return 0
s = start >> 1
e = n & start & 1
ans = sumXor(s - 1) ^ sumXor(s + n - 1)
return ans << 1 | e
go
func xorOperation(n, start int) (ans int) {
s, e := start>>1, n&start&1
ret := sumXor(s-1) ^ sumXor(s+n-1)
return ret<<1 | e
}
func sumXor(x int) int {
switch x & 3 {
case 0:
return x
case 1:
return 1
case 2:
return x | 1
default:
return 0
}
}
rust
impl Solution {
pub fn xor_operation(n: i32, start: i32) -> i32 {
let s = start >> 1;
let e = n & start & 1;
let ret = Solution::sum_xor(s - 1) ^ Solution::sum_xor(s + n - 1);
return ret << 1 | e
}
fn sum_xor(x: i32) -> i32 {
match x & 3 {
0 => x,
1 => 1,
2 => x | 1,
_ => 0
}
}
}

原題傳送門
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/312113.html
標籤:java
上一篇:【微信小程式爬蟲】表情包小程式圖文視頻教學,從零寫起,保姆教程!!!
下一篇:Java面向物件基礎
