• 剑指Offer28 最小的K个数(Partition函数应用+大顶堆)


    包含了Partition函数的多种用法

    以及大顶堆操作

      1 /*************************************************************************
      2     > File Name: 28_KLeastNumbers.cpp
      3     > Author: Juntaran
      4     > Mail: JuntaranMail@gmail.com
      5     > Created Time: 2016年08月31日 星期三 19时45分41秒
      6  ************************************************************************/
      7 
      8 #include <stdio.h>
      9 #include <bits/stdc++.h>
     10 
     11 using namespace std;
     12 
     13 
     14 // 大顶堆求最小K个数
     15 typedef multiset<int, greater<int> > intSet;
     16 typedef multiset<int, greater<int> >::iterator setIterator;
     17 
     18 void GetKLeastNumbers2(int* data, intSet& leastNumbers, int length, int k)
     19 {
     20     leastNumbers.clear();
     21     
     22     if (k<1 || length<k)
     23         return;
     24     
     25     for (int i = 0; i < length; ++i)
     26     {
     27         if (leastNumbers.size() < k)
     28             leastNumbers.insert(data[i]);
     29         
     30         else
     31         {
     32             setIterator Greatest = leastNumbers.begin();
     33             if (data[i] < *(leastNumbers.begin()))
     34             {
     35                 leastNumbers.erase(Greatest);
     36                 leastNumbers.insert(data[i]);
     37             }
     38         }
     39     }
     40     
     41     for (setIterator iter = leastNumbers.begin(); iter != leastNumbers.end(); ++iter)
     42     {
     43         printf("%d ", *iter); 
     44     }
     45     printf("
    ");
     46 }
     47 
     48 
     49 void swap(int* p, int* q)
     50 {
     51     int temp = *p;
     52     *p = *q;
     53     *q = temp;
     54 }
     55 
     56 // Partition函数应用
     57 int Partition(int* data, int length, int start, int end)
     58 {
     59     if (data==NULL || length<=0 || start<0 || end>=length)
     60         return -1;
     61     
     62     // 令数组第一个数字为标杆
     63     int index = start;                
     64     
     65     // 标杆与数组最后一个元素交换
     66     swap(&data[index], &data[end]);
     67     
     68     int small = start - 1;
     69     for (index = start; index < end; ++index)
     70     {
     71         if (data[index] < data[end])
     72         {
     73             ++ small;
     74             if (small != index)
     75             {
     76                 swap(&data[index], &data[small]);
     77             }
     78         }
     79     }
     80     ++ small;
     81     swap(&data[small], &data[end]);
     82     
     83     return small;
     84 }
     85 
     86 // 利用Partiton实现快排
     87 void quickSort(int* data, int length, int start, int end)
     88 {
     89     if (start==end || data==NULL || length<=0)
     90         return;
     91     
     92     int index = Partition(data, length, start, end);
     93     // printf("index is %d
    ", index);
     94     if (index > start)
     95         quickSort(data, length, start, index-1);
     96     if (index < end)
     97         quickSort(data, length, index+1, end);
     98 }
     99 
    100 // 利用Partition寻找出现次数超过一半的数 (中位数)
    101 int GetMoreThanHalf(int* input, int length)
    102 {
    103     if (input==NULL || length<=0)
    104         return -1;
    105     int start = 0;
    106     int end   = length - 1;
    107     int index = Partition(input, length, start, end);
    108     int middle = length >> 1;
    109     while (index != middle)
    110     {
    111         if (index > middle)
    112         {
    113             end = index - 1;
    114             index = Partition(input, length, start, end);
    115         }
    116         else
    117         {
    118             start = index + 1;
    119             index = Partition(input, length, start, end);
    120         }
    121     }
    122     int ret = input[middle];
    123     // 检验是否正确
    124     int count2 = 0;
    125     for (int i = 0; i < length; ++i)
    126     {
    127         if (input[i] == ret)
    128             count2 ++;
    129     }
    130     if (count2*2 > length)
    131     {
    132         printf("middle number is %d
    ", input[middle]);
    133         return ret;
    134     }
    135     else
    136     {
    137         printf("Not Find
    ");
    138         return -1;
    139     }
    140 }
    141 
    142 
    143 // 利用Partition寻找第K小的数
    144 int GetKthNumber(int* input, int length, int k)
    145 {
    146     if (input==NULL || length<=0 || k<=0 || k>length)
    147         return -1;
    148     int start = 0;
    149     int end   = length - 1;
    150     int index = Partition(input, length, start, end);
    151     while (index != k - 1)
    152     {
    153         if (index > k-1)
    154         {
    155             end = index-1;
    156             index = Partition(input, length, start, end);
    157         }
    158         else
    159         {
    160             start = index + 1;
    161             index = Partition(input, length, start, end);
    162         }
    163     }
    164     printf("Kth is %d
    ", input[index]);
    165     return input[index];
    166 }
    167 
    168 
    169 // 利用Partition寻找最小K个数
    170 void GetKLeastNumbers(int* input, int length, int* output, int k)
    171 {
    172     if (input==NULL || output==NULL || length<=0 || k<=0 || k>length)
    173     {
    174         return;
    175     }
    176     int start = 0;
    177     int end   = length - 1;
    178     int index = Partition(input, length, start, end);
    179     while (index != k - 1)
    180     {
    181         if (index > k-1)
    182         {
    183             end = index - 1;
    184             index = Partition(input, length, start, end);
    185         }
    186         else
    187         {
    188             start = index + 1;
    189             index = Partition(input, length, start, end);
    190         }
    191         // printf("index is %d
    ", index);
    192     }
    193     for (int i = 0; i < k; ++i)
    194         output[i] = input[i];
    195     
    196     for (int i = 0; i < k; ++i)
    197         printf("%d ", output[i]);
    198     printf("
    ");
    199 }
    200 
    201 
    202 int main()
    203 {
    204     int k = 5;
    205     int nums[] = {3,5,5,5,6,5,7,1,2,9};
    206     int length = 10;
    207     int output[k] = {0};
    208     
    209     // 快速排序
    210     quickSort(nums, length, 0, length-1);
    211     for (int i = 0; i < length; ++i)
    212         printf("%d ", nums[i]);
    213     printf("
    ");
    214     
    215     // 求最小K个数
    216     GetKLeastNumbers(nums, length, output, k);
    217     
    218     // 求第K大的数
    219     GetKthNumber(nums, length, k);
    220     
    221     // 求数组中超过一半的数(中位数)
    222     GetMoreThanHalf(nums, length);
    223     
    224     // 大顶堆求最小K个数
    225     intSet leastNumbers;
    226     GetKLeastNumbers2(nums, leastNumbers, length, k);
    227 }
  • 相关阅读:
    AC自动机
    概率DP
    POJ 1637 Sightseeing tour(混合图的欧拉回路)
    POJ 3233 Matrix Power Series(矩阵等比求和)
    HDU 2243 考研路茫茫——单词情结(AC自动机+DP+快速幂)
    HDU 3032 Nim or not Nim?(sg函数)
    HDU 3038 How Many Answers Are Wrong(种类并查集)
    HDU 4686 Arc of Dream(快速幂矩阵)
    HDU 3306 Another kind of Fibonacci(快速幂矩阵)
    HDU 3308 LCIS(线段树)
  • 原文地址:https://www.cnblogs.com/Juntaran/p/5831175.html
Copyright © 2020-2023  润新知