面試題:一個(gè)數(shù)組中除了兩個(gè)數(shù)字之外,其余數(shù)字均出現(xiàn)了兩次

題目?jī)?nèi)容

題目:一個(gè)數(shù)組中除了兩個(gè)數(shù)字之外,其余數(shù)字均出現(xiàn)了兩次,如{1, 2, 3, 4, 1, 2, 5, 5, 4, 7}.查找這兩個(gè)只出現(xiàn)一次的數(shù)字,要求時(shí)間復(fù)雜度為o(n),空間復(fù)雜度為o(1).

解法

  • 基礎(chǔ)知識(shí)

與(&):全1為1,有0則0.    0&0=0; 0&1=1;1&1=1;

或(|):有1則1,全0則0.    0|0=0; 0|1=1; 1|1=1;

異或(^):相同為0,不同為1. 1^1=0; 0^0=0; 0^1=1;

  • 思路如下:

  1. 將數(shù)組里全部數(shù)據(jù)異或一遍,由于相同數(shù)字異或結(jié)果為0,則這樣可以消除所有重復(fù)的數(shù)字,結(jié)果與兩個(gè)單次數(shù)字異或后的結(jié)果相同
  2. 因?yàn)閮烧呤遣煌臄?shù)字,結(jié)果一定有一位為1.這說(shuō)明在該位上這兩個(gè)單數(shù)一個(gè)為0一個(gè)為1.由此我們將數(shù)組分成兩部分,一部分為該位為0,另一部分為1,再分別對(duì)兩組異或最終得到的兩個(gè)數(shù)值就是單次出現(xiàn)的兩個(gè)數(shù)字
  • 解題步奏

  1. 全組異或
  2. 異或結(jié)果取出第一位不為0的位數(shù)
  3. 將數(shù)組數(shù)據(jù)根據(jù)改位數(shù)是否為零分開(kāi)異或,結(jié)果則為兩個(gè)單次數(shù)字

代碼如下

Talk is cheap, show you my code!

/**
 * Created by IDEA.
 * User: mc
 * Date: 19/2/13
 * Time: 上午9:19
 */
public class TowSingleNum
{
    public static void main(String[] args)
    {
        int[] num = {1, 2, 3, 4, 1, 2, 5, 5, 4, 7};
        execute(num);
    }

    /**
     * 獲取異或結(jié)果
     *
     * @param num
     * @return
     */
    private static int getSum(int[] num)
    {
        int sum = 0;
        for (int item : num) {
            sum ^= item;
        }
        return sum;
    }

    /**
     * 執(zhí)行入口
     *
     * @param num
     */
    public static void execute(int[] num)
    {
        int sum = getSum(num);
        int index = getIndex(sum);
        int num1 = 0, num2 = 0;
        for (int item : num) {
            if (judge(item, index)) {
                num1 ^= item;
            } else {
                num2 ^= item;
            }
        }
        System.out.printf("%d, %d", num1, num2);
    }

    /**
     * 劃分?jǐn)?shù)組
     *
     * @param num
     * @param index
     * @return
     */
    private static boolean judge(int num, int index)
    {
        return ((num >> index) & 1) == 0;
    }

    /**
     * 獲取第一個(gè)不同的位數(shù)
     *
     * @param sum
     * @return
     */
    private static int getIndex(int sum)
    {
        int index = 0;
        while ((1 & sum) == 0) {
            sum = sum >> 1;
            index++;
        }
        return index;
    }
}

寫(xiě)在最后的話(huà)

小菜雞最近想換工作,杭州有沒(méi)有需要菜鳥(niǎo)后端的(php/java),薪資要求14k+,java(沒(méi)有開(kāi)發(fā)經(jīng)驗(yàn))可以稍低一些.微信號(hào)bGlueXlhbmc5Mg==

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容