Leetcode Single Number 擴展

問題描述

Leetcode 137 Single Number II 僅出現一次的數字 中提出了一個更一般的問題:有一個數組,其中有一個元素出現了x次,其餘所有元素都出現了y次(x < y),找出這個出現了x次的元素,要求時間複雜度O(n),空間複雜度O(1)

解題思路

實際上,Leetcode 136 Single Number 僅出現一次的數字Leetcode 137 Single Number II 僅出現一次的數字 都是這個一般問題的特例。136是最特殊的一個例子,我們從中可以找到的規律不是很明顯;在137中我們已經給出使用one two three作爲掩碼來統計每一位上1的出現次數的方法,對於我們解決此題很有啓發。出現x次的情況下,我們用一個大小爲x的動態數組來存儲各掩碼即可,然後在每次獲取到一個數字後,循環更新所有的掩碼,最終第y個掩碼所代表的數字就是隻出現了y次的元素。

爲了統一處理,我們掩碼數組大小設爲x+1,用times[x+1]來表示,其中times[i]表示出現i次的位。

具體邏輯請看後面的代碼。

代碼

/**
 * 返回特殊的數字
 * 特殊數字僅出現y次,其餘數字均出現x次,x>0,y>0,x>y
 * @param nums 數字集合
 * @param numsSize 集合大小
 * @param x 普通數字出現次數
 * @param y 特殊數字出現次數
 */
int specialNumber(int *nums, int numsSize, int x, int y) {
    int num, change, i;
    int* times = (int*)malloc(sizeof(int) * (x + 1));
    for (i = 1; i <= x; ++i) *(times + i) = 0;
    while (numsSize) {
        *times = ~0; // 置全1,保證*(times+1)結果的正確性
        // 獲取當前要統計的數字
        num = *(nums + --numsSize); 
        for (i = x; i > 0; --i) { // 更新每一位掩碼
            change = *(times + i - 1) & num; // 獲得更新位
            *(times + i) |= change;  // 更新
            num &= ~change;          // 清空更新位
            *(times + i - 1) &= ~change;
        }
    }
    num = *(times + y);
    free(times);
    return num;
}

有了這個方法以後,我們在 Leetcode 136 Single Number 僅出現一次的數字 中的方法就可以如下實現:

/**
 * 返回僅出現一次的數字
 * 特殊數字僅出現1次,其餘數字均出現2次
 * @param nums 數字集合
 * @param numsSize 集合大小
 */
int singleNumber(int* nums, int numsSize) {
    int specialNumber(int*, int, int, int);
    return specialNumber(nums, numsSize, 2, 1);
}

同樣, 在Leetcode 137 Single Number II 僅出現一次的數字 中的方法就可以如下實現:

/**
 * 返回僅出現一次的數字
 * 特殊數字僅出現1次,其餘數字均出現3次
 * @param nums 數字集合
 * @param numsSize 集合大小
 */
int singleNumber(int* nums, int numsSize) {
    int specialNumber(int*, int, int, int);
    return specialNumber(nums, numsSize, 3, 1);
}

在leetcode上進行了驗證,136和137均Accept。

完整代碼 https://github.com/Orange1991/leetcode/blob/master/137/c/more.c

測試數據

[1,2,3,4,1,2,3,1,2,3] : each number appears 3 times expect for the special one appears 1 times, the special number is 4
[1,1,2,2,3,4,4,5,5,66,66] : each number appears 2 times expect for the special one appears 1 times, the special number is 3
[1,1,1,3,3,3,44,44,55,55,55,111,111,111] : each number appears 3 times expect for the special one appears 2 times, the special number is 44
[1] : each number appears 3 times expect for the special one appears 1 times, the special number is 1

2015/8/18

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章