最近在看位運算的知識,十分感嘆於位運算的博大精深,正好leetcode有 bit manipulation 的專題,正好拿來練練手。
給出乙個由不同的數字組成的陣列,列舉它的子陣列(子集)。
這道題我之前用遞迴解過,而且效率還不錯(beat 83.33%),解法如下不加詳述了:
/**
* @param nums
* @return
*/var ans, res, len;
function dfs(index, nums)
}var subsets = function(nums) );
ans = ,
res = ,
len = nums.length;
dfs(0, nums);
return ans;
};
如果用位運算解,這是一道經典的列舉子集。
比如我們有陣列[1, 2, 3]
,還是要用到標誌位的概念,全集為1 1 1
,全集表示都取,它的子集有1 0 1
、1 1 0
、1 0 0
等等,我們通過列舉子集,然後再通過子集獲取原來陣列的元素即可。
比如子集1 0 1
,我們可以依次獲取最右邊的1,然後根據獲取的1的大小判斷陣列元素的index位置從而獲取陣列,之後把該1置為0即可。
/**
* @param nums
* @return
*/var subsets = function(nums) );
var all = (1 << nums.length) - 1
, ans = ;
// 列舉子集
for (i = all; i; i = (i - 1) & all)
ans.push(res);
} // 子集的列舉沒有0,所以要special insert
ans.push();
return ans;
};
判斷乙個數是不是2的冪。如果乙個數是2的冪,那麼該數與上該數-1為0。我們以8舉例:
1 0 0 0
0 1 1 1
很明顯,上面兩數做與運算的結果是0。但是有個特殊的情況是,0 & (0 - 1) === 0
,所以我們還得判斷該數為正。
/**
* @param n
* @return
*/var ispoweroftwo = function(n) ;
這裡加強下,如果知道某數是2的冪,求解這個指數值。即math.pow(2, x) = n
,求x的值。
也很簡單,用個log的換底公式(其實沒有涉及位運算):
return math.log(n) / math.in2;
給出乙個0~n組成的陣列[0, 1, 2, 3 ... n]
,從中隨即去掉乙個數字,給你新的陣列,求解被去掉的數字。比如給你[0, 1, 3]
,返回2
。
這題涉及^
運算的性質:
// if
a ^ b = c;
// then
a ^ c = b;
b ^ c = a;
解法也就呼之欲出了。還是假設陣列[0, 1, 3]
,我們可以知道n為3(等於陣列長度),從而可以計算出0 ^ 1 ^ 2 ^ 3
的值,我們把它賦值給c;然後我們計算所給陣列的元素的異或值,賦值給a,假設被捨棄的元素為b,我們可以得到如下等式:
a ^ b = c;
根據前邊所講:
b = a ^ c;
完整**:
/**
* @param n
* @return
*//**
* @param nums
* @return
*/var missingnumber = function(nums) );
var b = nums.reduce(function(pre, item, index) , nums.length);
return a ^ b;
};
位運算題目彙總
給你乙個整數陣列 arr 請你將陣列中的元素按照其二進位制表示中數字 1 的數目公升序排序。如果存在多個數字二進位制中 1 的數目相同,則必須將它們按照數值大小公升序排列。請你返回排序後的陣列。輸入 arr 0 1,2 3,4 5,6 7,8 輸出 0,1,2,4,8,3,5,6,7 解釋 0 是唯...
位運算題目
今天看到牛客網的一些題目,非常經典。解法基本也都很熟悉,所以特地做個總結,後續慢慢補充。先上題目 數字中的二進位制有多少個1 這裡的數字並不關心它的符號,所以即便是負數,只需要得到二進位制中1的個數就可以了。但是在python中,對於負數的右移運算,符號位會保留,這樣在執行迴圈語句的右移操作時,首位...
位運算小結及位運算題目小練
按位與運算子 是雙目運算子。其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1,否則為0。參與運算的數以補碼方式出現。運算規則 0 0 0 0 1 0 1 0 0 1 1 1 舉例 9 00001001 5 00000101 1 00000001 00001001 ...