給定一個整數序列,KiKi想把其中的重復的整數去掉,并將去重后的序列從小到大排序輸出。
輸入描述
第一行,輸入一個整數n,表示序列有n個整數。
第二行輸入n個整數(每個整數大于等于1,小于等于1000),整數之間用空格分隔。
輸出描述
去重并且從小到大排列的整數序列,整數之間用空格分隔。
對于這道題的,我提供了兩種解法,一種容易想到,一種非常巧妙。
暴力求解
思路:對于給定的一個整數序列,我們應該先排序,而后去重,先排序可以把重復的值排在一起,這樣重復值會比較容易去除。在本題中,我們采用冒泡排序,冒泡排序在之前的文章中講過了,這里提供一個鏈接,如果需要請查看冒泡排序。本文重點討論如何去重。
當排序完成后,要進行去重,下面這張圖解釋了去重的原理,也很簡單,如果相鄰兩個數值相等,那么將后n-1個數整體前移,覆蓋前n-1個數,最終剩下n-1個數,以此類推。?
?
#include <stdio.h>
void bubble_sort(int* p, int sz)
{int i=0;for(i=0;i<sz-1;i++){int j=0;for(j=0;j<sz-1-i;j++){if(p[j]>p[j+1]){int tmp=0;tmp=p[j];p[j]=p[j+1];p[j+1]=tmp;}}}}int main(){int n=0;int i=0;int arr[1000]={0};scanf("%d",&n);//輸入n個元素for(i=0;i<n;i++){scanf("%d",&arr[i]);}//1.排序bubble_sort(arr,n);//2.去重//比較n-1對for(i=0;i<n-1;i++){if(arr[i]==arr[i+1]){int k=i;for(k=i;k<n-1;k++){arr[k]=arr[k+1];}n--;//去重完一對,n少一個i--;}}//3.打印for(i=0;i<n;i++){printf("%d ",arr[i]);}return 0;
}
優雅解法
這里還有一個巧妙的解法,我們創建一個1001大小的數組,這樣數組最大下標就是1000了,因為每個整數大于等于1,小于等于1000,所以我們可以把整數n放到數組下標為n的位置,這樣重復值會被多次放到同一個下標的位置(比如5重復了三次,那么5會被放到數組下標為5的位置3次,這樣就起到去重的作用),同時,數字是按照坐標順序放置,自然而然已經由小到大排好序了,我們只需按順序打印值不為0的元素即可。
#include <stdio.h>
int main()
{int n=0;int arr[1001]={0};int i=0;int m=0;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d",&m);//值為m的元素放到下標為m的位置arr[m]=m;}for(i=0;i<=1000;i++){if(arr[i] != 0)printf("%d ",arr[i]);}return 0;
}
?
?