<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          位運(yùn)算的慣用套路,都在這兒!(算法 NO.2)

          共 3250字,需瀏覽 7分鐘

           ·

          2020-08-10 18:01

          本文所列題目來自 LeetCode 中國網(wǎng)站,屬于算法面試中關(guān)于位運(yùn)算的經(jīng)典高頻考題。題解由 Doocs 開源社區(qū) leetcode 項目維護(hù)者提供。

          目前已經(jīng)有超過 50 位開發(fā)者參與了此項目,期待你的加入!

          項目地址:https://github.com/doocs/leetcode

          題目1

          題目描述

          一個整型數(shù)組?nums?里除兩個數(shù)字之外,其他數(shù)字都出現(xiàn)了兩次。請寫程序找出這兩個只出現(xiàn)一次的數(shù)字。要求時間復(fù)雜度是O(n),空間復(fù)雜度是O(1)。

          示例 1:

          輸入:nums = [4,1,4,6]輸出:[1,6]  [6,1]

          示例 2:

          輸入:nums = [1,2,10,4,1,4,3,3]輸出:[2,10]  [10,2]

          限制:

          ?2 <= nums <= 10000

          解法

          異或運(yùn)算求解。

          首先明確,兩個相同的數(shù)異或之后的結(jié)果為 0。對該數(shù)組所有元素進(jìn)行異或運(yùn)算,結(jié)果就是兩個只出現(xiàn)一次的數(shù)字異或的結(jié)果。找出這個結(jié)果中某個二進(jìn)制位為 1 的位置,之后對數(shù)組所有元素進(jìn)行分類,二進(jìn)制位為 0 的異或到 a,二進(jìn)制位為 1 的異或到 b,結(jié)果就是 a,b。

          Python3

          class Solution:    def singleNumbers(self, nums: List[int]) -> List[int]:        xor_res = 0        for num in nums:            xor_res ^= num        pos = 0        while (xor_res & 1) == 0:            pos += 1            xor_res >>= 1        a = b = 0        for num in nums:            t = num >> pos            if (t & 1) == 0:                a ^= num            else:                b ^= num        return [a, b]

          Java

          class Solution {    public int[] singleNumbers(int[] nums) {        int xor = 0;        for (int num : nums) {            xor ^= num;        }        int pos = 0;        while ((xor & 1) == 0) {            ++pos;            xor >>= 1;        }        int a = 0, b = 0;        for (int num : nums) {            int t = num >> pos;            if ((t & 1) == 0) {                a ^= num;            } else {                b ^= num;            }        }        return new int[] {a, b};    }}

          題目2

          題目描述

          在一個數(shù)組?nums?中除一個數(shù)字只出現(xiàn)一次之外,其他數(shù)字都出現(xiàn)了三次。請找出那個只出現(xiàn)一次的數(shù)字。

          示例 1:

          輸入:nums = [3,4,3,3]輸出:4

          示例 2:

          輸入:nums = [9,1,7,9,7,9,7]輸出:1

          限制:

          ?1 <= nums.length <= 10000?1 <= nums[i] < 2^31

          解法

          統(tǒng)計所有數(shù)字每個位中 1 出現(xiàn)的次數(shù),對于某個位,1 出現(xiàn)的次數(shù)一定是 3 的倍數(shù) +1 或 0。對這個數(shù) %3 得到的結(jié)果就是那個出現(xiàn)一次的數(shù)字在該位上的值。

          Python3

          class Solution:    def singleNumber(self, nums: List[int]) -> int:        bits = [0 for _ in range(32)]        for num in nums:            for i in range(32):                bits[i] += (num & 1)                num >>= 1        res = 0        for i in range(32):            if bits[i] % 3 == 1:                res += (1 << i)        return res

          Java

          class Solution {    public int singleNumber(int[] nums) {        int[] bits = new int[32];        for (int num : nums) {            for (int i = 0; i < 32; ++i) {                bits[i] += (num & 1);                num >>= 1;            }        }        int res = 0;        for (int i = 0; i < 32; ++i) {            if (bits[i] % 3 == 1) {                res += (1 << i);            }        }        return res;    }}

          題目3

          題目描述

          集合?S?包含從1到?n?的整數(shù)。不幸的是,因為數(shù)據(jù)錯誤,導(dǎo)致集合里面某一個元素復(fù)制了成了集合里面的另外一個元素的值,導(dǎo)致集合丟失了一個整數(shù)并且有一個元素重復(fù)。

          給定一個數(shù)組?nums?代表了集合?S?發(fā)生錯誤后的結(jié)果。你的任務(wù)是首先尋找到重復(fù)出現(xiàn)的整數(shù),再找到丟失的整數(shù),將它們以數(shù)組的形式返回。

          示例 1:

          輸入: nums = [1,2,2,4]輸出: [2,3]

          注意:

          1.給定數(shù)組的長度范圍是[2, 10000]2.給定的數(shù)組是無序的。

          解法

          首先使用 1 到 n 的所有數(shù)字做異或運(yùn)算,然后再與數(shù)組中的所有數(shù)字異或,得到的值就是缺失數(shù)字與重復(fù)的數(shù)字異或的結(jié)果。

          接著計算中這個值中其中一個非零的位 pos。然后 pos 位是否為 1,將 nums 數(shù)組的元素分成兩部分,分別異或;接著將?1~n?的元素也分成兩部分,分別異或。得到的兩部分結(jié)果分別為 a,b,即是缺失數(shù)字與重復(fù)數(shù)字。

          最后判斷數(shù)組中是否存在 a 或 b,若存在 a,說明重復(fù)數(shù)字是 a,返回?[a,b],否則返回?[b,a]。

          Python3

          class Solution:    def findErrorNums(self, nums: List[int]) -> List[int]:        res = 0        for num in nums:            res ^= num        for i in range(1, len(nums) + 1):            res ^= i        pos = 0        while (res & 1) == 0:            res >>= 1            pos += 1        a = b = 0        for num in nums:            if ((num >> pos) & 1) == 0:                a ^= num            else:                b ^= num        for i in range(1, len(nums) + 1):            if ((i >> pos) & 1) == 0:                a ^= i            else:                b ^= i        for num in nums:            if num == a:                return [a, b]        return [b, a]

          Java

          class Solution {    public int[] findErrorNums(int[] nums) {        int res = 0;        for (int num : nums) {            res ^= num;        }        for (int i = 1, n = nums.length; i < n + 1; ++i) {            res ^= i;        }        int pos = 0;        while ((res & 1) == 0) {            res >>= 1;            ++pos;        }        int a = 0, b = 0;        for (int num : nums) {            if (((num >> pos) & 1) == 0) {                a ^= num;            } else {                b ^= num;            }        }        for (int i = 1, n = nums.length; i < n + 1; ++i) {            if (((i >> pos) & 1) == 0) {                a ^= i;            } else {                b ^= i;            }        }        for (int num : nums) {            if (num == a) {                return new int[]{a, b};            }        }        return new int[]{b, a};    }}

          題目4

          題目描述

          請實現(xiàn)一個函數(shù),輸入一個整數(shù),輸出該數(shù)二進(jìn)制表示中 1 的個數(shù)。例如,把 9?表示成二進(jìn)制是 1001,有 2 位是 1。因此,如果輸入 9,則該函數(shù)輸出 2。

          示例 1:

          輸入:00000000000000000000000000001011輸出:3解釋:輸入的二進(jìn)制串 00000000000000000000000000001011?中,共有三位為 '1'。

          示例 2:

          輸入:00000000000000000000000010000000輸出:1解釋:輸入的二進(jìn)制串 00000000000000000000000010000000?中,共有一位為 '1'。

          示例 3:

          輸入:11111111111111111111111111111101輸出:31解釋:輸入的二進(jìn)制串 11111111111111111111111111111101 中,共有 31 位為 '1'。

          解法

          n & (n - 1)?會消除 n 中最后一位中的 1。

          Python3

          class Solution:    def hammingWeight(self, n: int) -> int:        res = 0        while n:            n &= (n - 1)            res += 1        return res

          Java

          public class Solution {    // you need to treat n as an unsigned value    public int hammingWeight(int n) {        int res = 0;        while (n != 0) {            n &= (n - 1);            ++res;        }        return res;    }}

          長按識別下圖二維碼,關(guān)注公眾號「Doocs開源社區(qū)」,第一時間跟你們分享好玩、實用的技術(shù)文章與業(yè)內(nèi)最新資訊。



          瀏覽 31
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  不卡乱伦 | 婷婷五月成人激情 | 韩国精品婷婷 | 国产黄视 | 青娱乐免费精品视频1 |