統計陣列中各元素出現次數
1.問題描述
給定一大小為N的整數陣列,其元素取值範圍為[1,N],請統計各元素出現的次數,並要求時間複雜度為O(n),空間複雜度為O(1)。
2.思路
若沒有空間的限制,則可直接開闢一個大小等於元素最大值的陣列對各元素進行統計,並且順帶還進行了時間複雜度為O(n)的排序(比快速排序還快哦)。
統計n個元素出現的次數,每個元素對應一個次數資訊需要儲存,那麼就需要n個空間;而現在不讓開闢新的n個空間,這些資訊又必須要記錄,那你說該放在哪?當然是原陣列中囉!
不過問題又來了,原陣列中的值豈不是會被覆蓋掉?好吧,可以先把陣列中原來的值拿出來後放跟次數相關的資訊就沒問題了。對於拿出來的這個值,必須即拿即用(不然堆積起來又要n個空間來儲存),由於元素取值範圍為[1,N],因此可以將這個值當作陣列的索引來訪問下個元素(記得-1)。還有個問題,若像數字5出現了2次,第一次遇到數字5時,將a[4]中原來的值取出用來訪問下一個元素並將a[4]清零後+1表示5已經出現過1次了;第二次遇到數字5時問題就來了,不能將現在a[4]中的值取出用來訪問下個元素,只能將a[4]加1表示又遇到5了。也就是說一個元素沒被訪問過和被訪問過兩種狀態得區別對待,那麼,怎麼知道元素有沒有被訪問過呢?之前每個元素需要記錄次數相關資訊,現在每個元素又要體現有沒有被碰過,如何讓一個值體現這兩種屬性呢?我們知道一個數除了大小外還有正負這個屬性,因此這裡便將被訪問過的元素設為負值(因為原陣列中元素均為正值且沒被碰過),於是第一次遇到某個元素時現將它清零後-1,以後每遇到一次就-1。最後將值取反便得到各元素對應的出現次數。
最後還有一個問題,就是當再次訪問某個元素時,由於其值為負表示其出現的次數,就沒辦法從中得到訪問下一元素所需的資訊,程式沒辦法進行下去!因此,這個時候需要手動指定下一個訪問的元素是誰,當然是從頭到尾全部指定一遍(儘管被指定的元素可能之前已經被訪問過了,沒關係,再指定下一個就好了),既保證所用元素都被至少訪問過一次又可以使整個過程終止。例如,第一次指定a[0],第二次指定a[1],...,直到a[n-1]為止。還請注意的是,通過手動指定而訪問到的元素只需要將值清零而不用-1,因為沒有數字指向它,當然出現的次數也就是0囉!
題外話:一個問題之所以不像它看上去那麼簡單,除了需要奇葩的想法外,就是要處理各種特殊的狀況。
3.程式碼
#include <stdio.h>
#define N 7
void elementCounter(int array[],int n);
int main(void)
{//測試用例
int array[N]={5,5,2,4,1,7,5};
elementCounter(array,N);
return 0;
}
void elementCounter(int array[],int n)
{
int index;//訪問下一個元素用的索引
int flag;//標誌此次訪問是否為手動指定的
int temp;
int i;
//統計元素出現次數
for(i=0,index=0,flag=1;i<n; )//因為手動指定從array[0]開始,flag設為1
{
if(array[index]>0)//某元素第一次被訪問
{
temp=array[index];
array[index]=flag-1;//若是被手動指定訪問到的,則flag=1,其值為0不算其出現過
index=temp-1;//自動指定下一個訪問元素
flag=0;//因為是第一次被訪問,其值可以用來訪問下個元素,不需要手動指定
}
else//某元素不是第一次被訪問
{
array[index]=flag-1+array[index];若是被手動指定訪問到的,則flag=1,其出現次數不變
index=++i;//手動指定下個訪問元素
flag=1;//標誌下一次訪問為手動指定的
}
}
//列印元素出現次數
for(i=0;i<N;i++)
{
if(array[i]!=0)//不列印沒出現過的
printf("數字%d出現%d次\n",i+1,-array[i]);
}
}
相關文章
- 統計陣列中各數字(元素)出現的次數陣列
- Matlab 統計陣列中各數字(元素)出現的次數Matlab陣列
- 統計陣列元素中每個元素出現的次數陣列
- matlab如何統計矩陣各元素的出現次數Matlab矩陣
- 陣列中每個陣列元素出現的次數陣列
- js常見演算法(一):陣列去重,打亂陣列,統計陣列各個元素出現的次數, 字串各個字元的出現次數,獲取地址連結的各個引數JS演算法陣列字串字元
- 統計陣列個元素出現的個數陣列
- 找出陣列中元素出現次數超過陣列長度一半的元素陣列
- MATLAB自帶的函式tabulate統計一個陣列中各數字(元素)出現的頻數、頻率Matlab函式陣列
- 計算陣列元素重複的個數,並把出現次數相同的統計一起。陣列
- matlab——統計相同元素出現的次數Matlab
- Matlab tabulate統計數字出現的次數,如果陣列中出現0Matlab陣列
- js找出陣列中出現最多的元素和次數JS陣列
- 找出陣列中只出現一次的數字陣列
- 找出陣列中第 k 大的數字及其出現次數陣列
- matlab之對元素出現的次數進行統計Matlab
- 利用HashMap統計字串各個字元出現的次數HashMap字串字元
- 劍指 Offer 56 - I. 陣列中數字出現的次數陣列
- 【轉】matlab之對元素出現的次數進行統計Matlab
- JZ-040-陣列中只出現一次的數字陣列
- 給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。陣列
- **呼叫MapReduce對檔案中各個單詞出現的次數進行統計**
- 在Linux中呼叫MapReduce對檔案中各個單詞出現次數進行統計Linux
- 陣列元素的數量陣列
- 在其它數都出現k次的陣列中找到只出現一次的數陣列
- 返回陣列中的最大元素個數陣列
- JavaScript統計字元出現的次數JavaScript字元
- 統計字串出現的次數(C)字串
- 統計numpy陣列中最頻繁出現的值陣列
- 計蒜客 移除陣列中的重複元素陣列
- Java小程式--統計指定字串中字元 ‘a’ 出現的次數Java字串字元
- 給定一個大小為 n 的陣列,找到其中的眾數。眾數是指在陣列中出現次數大於 ⌊ n/2 ⌋ 的元素。陣列
- leetcode:462. 最少移動次數使陣列元素相等 II(數學,中等)LeetCode陣列
- Minimum Moves to Equal Array Elements 最小移動次數使陣列元素相等陣列
- iOS 用簡便的方法統計兩個陣列中不同的元素iOS陣列
- PHP陣列學習之計算陣列元素總和PHP陣列
- 找到陣列中出現特定次數數字的問題陣列
- 定義方法統計集合中指定元素出現的次數,如“a“ 3,“b“ 2,“c“ 1
- lc3041 修改陣列後最大化陣列中的連續元素數目陣列