鱼C论坛

 找回密码
 立即注册
查看: 1896|回复: 1

[技术交流] 414_第三大的数

[复制链接]
发表于 2019-6-3 17:49:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. /*
  2. 给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。
  3. 示例 1
  4. 输入 [3, 2, 1]
  5. 输出 1
  6. 解释 第三大的数是 1.
  7. 示例 2
  8. 输入 [1, 2]
  9. 输出 2
  10. 解释 第三大的数不存在, 所以返回最大的数 2 .
  11. 示例 3
  12. 输入 [2, 2, 3, 1]
  13. 输出 1
  14. 解释 注意,要求返回第三大的数,是指第三大且唯一出现的数。
  15. 存在两个值为2的数,它们都排第二。
  16. */
复制代码



解法:堆排序后再取
  1. int     count = 0;
  2. int*    arr   = NULL;


  3. void _swap(int* a, int*b)
  4. {
  5.     int c;
  6.     c = *a;
  7.     *a = *b;
  8.     *b = c;
  9. }


  10. void shift_up( int ind )
  11. {
  12.     while(  (arr[ind/2] < arr[ind])   /*大根堆:父节点的值小于新加入的孩子节点,且 ind/2 至少为1 均满足时才交换*/
  13.           &&(ind > 1)
  14.          )
  15.     {
  16.         _swap(&arr[ind/2],&arr[ind]);   /* 交换 */
  17.          ind /= 2;                      /* 待比较对象迁移到父节点*/
  18.     };
  19. }

  20. void shift_down( int ind )
  21. {
  22.     int moreBiggerIndex = 0;
  23.     while(2*ind <=count) /* 有左孩子就是有孩子*/
  24.     {
  25.         moreBiggerIndex = 2*ind;
  26.         if(  (moreBiggerIndex+1<=count)
  27.            &&(arr[moreBiggerIndex+1]>arr[moreBiggerIndex])
  28.         )
  29.         {
  30.             moreBiggerIndex += 1; /* 更新到右孩子*/   
  31.         }
  32.         if(arr[ind]<arr[moreBiggerIndex])
  33.         {
  34.             _swap(&arr[ind],&arr[moreBiggerIndex]);
  35.             ind = moreBiggerIndex;
  36.         }
  37.         else
  38.         {
  39.             break;
  40.         }
  41.     };
  42. }


  43. int search_ele(int num)
  44. {
  45.     int ret_val = 0;
  46.    
  47.     for(int i = 1; i <= count ; i++)
  48.     {
  49.         if(arr[i] == num)
  50.         {
  51.             ret_val = 1;
  52.             break;
  53.         }
  54.     }   
  55.     return ret_val ;
  56. }

  57. void insert_ele(int num)
  58. {
  59.     if(search_ele(num) == 1)
  60.     {
  61.         return;
  62.     }
  63.     else
  64.     {
  65.         arr[count+1] = num;
  66.         count ++;
  67.         shift_up(count);        
  68.     }
  69. }

  70. int getMax(int* ret_val)
  71. {
  72.     int item;
  73.     if(count < 1)
  74.     {
  75.         //cout << "此二叉堆已经为空,无法进行取出操作" << endl;
  76.         return -1;
  77.     }
  78.    
  79.     /* 获得根节点 */
  80.     item = arr[1];
  81.     _swap(&arr[1],&arr[count]); /*把最后一个和第一个进行交换*/
  82.     count--;                    /* 进行计数调整*/
  83.     shift_down(1);              /*把交换上来的数进行shift_down操作,以使堆继续满足大根堆的性质*/

  84.     *ret_val = item;
  85.     return 0;
  86. }

  87. int thirdMax(int* nums, int numsSize)
  88. {
  89.     int ret_val = 0;
  90.     arr = (int*)malloc(sizeof(int)*(numsSize+1));
  91.     if(arr == NULL)
  92.     {
  93.         return 0;
  94.     }
  95.     else
  96.     {
  97.         memset(arr,0,sizeof(int)*(numsSize+1));
  98.     }
  99.    
  100.     for(int i = 0 ; i < numsSize ; i++)
  101.     {
  102.         insert_ele(nums[i]);
  103.     }

  104.     if (count < 3)
  105.     {
  106.         getMax(&ret_val);
  107.     }
  108.     else
  109.     {
  110.         for (int i = 0; i < 3; i++)
  111.         {
  112.             if (getMax(&ret_val) == -1)
  113.             {
  114.                 break;
  115.             }
  116.         }
  117.     }
  118.     free(arr);
  119.     arr = NULL;
  120.     count = 0;
  121.     return ret_val;
  122. }
复制代码


  1. /*
  2. 资源和用时都爆炸了。。
  3. 执行用时 : 148 ms, 在Third Maximum Number的C提交中击败了9.00% 的用户
  4. 内存消耗 : 7.6 MB, 在Third Maximum Number的C提交中击败了6.67% 的用户
  5. */
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-6-3 17:51:20 | 显示全部楼层
解法2:
利用4个元素的小顶堆进行优先队列处理,降低复杂度到O(nlog4)即O(n) ,编写中。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 18:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表