JZ-C-30

剑指offer第三十题:最小的k个数

  1 //============================================================================
  2 // Name        : JZ-C-30.cpp
  3 // Author      : Laughing_Lz
  4 // Version     :
  5 // Copyright   : All Right Reserved
  6 // Description : 最小的k个数
  7 //============================================================================
  8
  9 #include <iostream>
 10 #include <stdio.h>
 11 #include <set>
 12 #include <vector>
 13 #include "Array.h"
 14 using namespace std;
 15
 16 using namespace std;
 17
 18 // ====================方法1:同样可利用分治法====================
 19 void GetLeastNumbers_Solution1(int* input, int n, int* output, int k)
 20 {
 21     if(input == NULL || output == NULL || k > n || n <= 0 || k <= 0)
 22         return;
 23
 24     int start = 0;
 25     int end = n - 1;
 26     int index = Partition(input, n, start, end);
 27     while(index != k - 1)
 28     {
 29         if(index > k - 1)
 30         {
 31             end = index - 1;
 32             index = Partition(input, n, start, end);
 33         }
 34         else
 35         {
 36             start = index + 1;
 37             index = Partition(input, n, start, end);
 38         }
 39     }
 40
 41     for(int i = 0; i < k; ++i)
 42         output[i] = input[i];//查找后,放入output数组
 43 }
 44
 45 // ====================方法2:堆、红黑树:set、multiset都是基于红黑树实现的====================
 46 typedef multiset<int, greater<int> >            intSet;
 47 typedef multiset<int, greater<int> >::iterator  setIterator;
 48
 49 void GetLeastNumbers_Solution2(const vector<int>& data, intSet& leastNumbers, int k)
 50 {
 51     leastNumbers.clear();
 52
 53     if(k < 1 || data.size() < k)
 54         return;
 55
 56     vector<int>::const_iterator iter = data.begin();
 57     for(; iter != data.end(); ++ iter)
 58     {
 59         if((leastNumbers.size()) < k)
 60             leastNumbers.insert(*iter);
 61
 62         else
 63         {
 64             setIterator iterGreatest = leastNumbers.begin();
 65
 66             if(*iter < *(leastNumbers.begin()))
 67             {
 68                 leastNumbers.erase(iterGreatest);
 69                 leastNumbers.insert(*iter);
 70             }
 71         }
 72     }
 73 }
 74
 75 // ====================测试代码====================
 76 void Test(char* testName, int* data, int n, int* expectedResult, int k)
 77 {
 78     if(testName != NULL)
 79         printf("%s begins: \n", testName);
 80
 81     vector<int> vectorData;
 82     for(int i = 0; i < n; ++ i)
 83         vectorData.push_back(data[i]);
 84
 85     if(expectedResult == NULL)
 86         printf("The input is invalid, we don‘t expect any result.\n");
 87     else
 88     {
 89         printf("Expected result: \n");
 90         for(int i = 0; i < k; ++ i)
 91             printf("%d\t", expectedResult[i]);
 92         printf("\n");
 93     }
 94
 95     printf("Result for solution1:\n");
 96     int* output = new int[k];
 97     GetLeastNumbers_Solution1(data, n, output, k);
 98     if(expectedResult != NULL)
 99     {
100         for(int i = 0; i < k; ++ i)
101             printf("%d\t", output[i]);
102         printf("\n");
103     }
104
105     delete[] output;
106
107     printf("Result for solution2:\n");
108     intSet leastNumbers;
109     GetLeastNumbers_Solution2(vectorData, leastNumbers, k);
110     printf("The actual output numbers are:\n");
111     for(setIterator iter = leastNumbers.begin(); iter != leastNumbers.end(); ++iter)
112         printf("%d\t", *iter);
113     printf("\n\n");
114 }
115
116 // k小于数组的长度
117 void Test1()
118 {
119     int data[] = {4, 5, 1, 6, 2, 7, 3, 8};
120     int expected[] = {1, 2, 3, 4};
121     Test("Test1", data, sizeof(data) / sizeof(int), expected, sizeof(expected) / sizeof(int));
122 }
123
124 // k等于数组的长度
125 void Test2()
126 {
127     int data[] = {4, 5, 1, 6, 2, 7, 3, 8};
128     int expected[] = {1, 2, 3, 4, 5, 6, 7, 8};
129     Test("Test2", data, sizeof(data) / sizeof(int), expected, sizeof(expected) / sizeof(int));
130 }
131
132 // k大于数组的长度
133 void Test3()
134 {
135     int data[] = {4, 5, 1, 6, 2, 7, 3, 8};
136     int* expected = NULL;
137     Test("Test3", data, sizeof(data) / sizeof(int), expected, 10);
138 }
139
140 // k等于1
141 void Test4()
142 {
143     int data[] = {4, 5, 1, 6, 2, 7, 3, 8};
144     int expected[] = {1};
145     Test("Test4", data, sizeof(data) / sizeof(int), expected, sizeof(expected) / sizeof(int));
146 }
147
148 // k等于0
149 void Test5()
150 {
151     int data[] = {4, 5, 1, 6, 2, 7, 3, 8};
152     int* expected = NULL;
153     Test("Test5", data, sizeof(data) / sizeof(int), expected, 0);
154 }
155
156 // 数组中有相同的数字
157 void Test6()
158 {
159     int data[] = {4, 5, 1, 6, 2, 7, 2, 8};
160     int expected[] = {1, 2};
161     Test("Test6", data, sizeof(data) / sizeof(int), expected, sizeof(expected) / sizeof(int));
162 }
163
164 // 输入空指针
165 void Test7()
166 {
167     int* expected = NULL;
168     Test("Test7", NULL, NULL, expected, 0);
169 }
170
171 int main(int argc, char** argv)
172 {
173     Test1();
174     Test2();
175     Test3();
176     Test4();
177     Test5();
178     Test6();
179     Test7();
180
181     return 0;
182 }

关于Partition方法:

 1 // 《剑指Offer——名企面试官精讲典型编程题》代码
 2 // 著作权所有者:何海涛
 3
 4 #include <stdlib.h>
 5 #include <stdio.h>
 6 #include "Array.h"
 7 #include <exception>
 8
 9 // Random Partition
10 int RandomInRange(int min, int max) {
11     int random = rand() % (max - min + 1) + min;
12     return random;
13 }
14
15 void Swap(int* num1, int* num2) {
16     int temp = *num1;
17     *num1 = *num2;
18     *num2 = temp;
19 }
20
21 int Partition(int data[], int length, int start, int end) {
22     if (data == NULL || length <= 0 || start < 0 || end >= length) {
23         printf("Invalid Parameters");
24         throw new std::exception();//这里括号里为什么不能加msg???!!!
25     }
26     int index = RandomInRange(start, end);
27     Swap(&data[index], &data[end]);
28
29     int small = start - 1;
30     for (index = start; index < end; ++index) {
31         if (data[index] < data[end]) {
32             ++small;
33             if (small != index)
34                 Swap(&data[index], &data[small]);
35         }
36     }
37
38     ++small;
39     Swap(&data[small], &data[end]);
40
41     return small;
42 }
时间: 2024-07-30 19:59:05

JZ-C-30的相关文章

深度优先搜索 codevs 1064 虫食算

codevs 1064 虫食算 2004年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045    +    8468#6633       44445506978 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5

[芯片] 2、接口技术&#183;实验二&#183;定时/计数器8253

目录 一.实验目的和要求 二.实验原理与背景 三.实验具体的内容 3-1.计数器方式0实验 3-2.计数器方式3实验 3-3.计数器级联实验 四.实验的代码说明 4-1.计数器方式0实验代码及说明 4-2.计数器方式3实验代码及说明 4-3.计数器级联实验代码及说明 五.实验结果的分析 5-1.计数方式0实验分析 5-2.计数方式3实验分析 5-3.级联方式实验分析 附录资料 一.实验目的和要求 学会8253芯片和微机接口原理和方法. 掌握8253定时\计数芯片的基本工作原理.工作方式和编程原理

百度,宫颈癌和房和附件是房价将阿斯顿发

http://www.ebay.com/cln/vnqus-aoi2rh42/ebay/157776573019/2015.01.30 http://www.ebay.com/cln/vnqus-aoi2rh42/ebay/157776590019/2015.01.30 http://www.ebay.com/cln/vnqus-aoi2rh42/ebay/157776608019/2015.01.30 http://www.ebay.com/cln/vnqus-aoi2rh42/ebay/15

百度,换房间啊回复大花洒减肥哈的时间放假了圣诞节

http://www.ebay.com/cln/yous-ypfkprfc/ebay/157911546014/2015.01.30 http://www.ebay.com/cln/yous-ypfkprfc/ebay/157911557014/2015.01.30 http://www.ebay.com/cln/yous-ypfkprfc/ebay/157911568014/2015.01.30 http://www.ebay.com/cln/dinjag.bwlw17m/ebay/15814

日志文件cpm

08/30/14 11:19:29,856 INFO =============CDN BaseLib is starting......!================ pid = 5894 [src/main.cpp:417] 08/30/14 11:19:29,857 TRACE Enter InitThreadPool() [src/main.cpp:260] 08/30/14 11:19:29,857 TRACE Exit InitThreadPool() [src/main.cpp

《30天自制操作系统》笔记(02)——导入C语言

<30天自制操作系统>笔记(02)--导入C语言 进度回顾 在上一篇,记录了计算机开机时加载IPL程序(initial program loader,一个nas汇编程序)的情况,包括IPL代码(helloos.nas).编译生成helloos.img文件.用虚拟机QEMU加载helloos.img.制作U盘启动盘和用物理机加载helloos.img. 计算机启动时会自动加载和执行IPL程序,但IPL程序只能占用512字节.若直接用IPL写OS,空间不够用.所以IPL程序一般用于将真正的OS程序

《30天自制操作系统》读书笔记(3) 引入C语言

这一次的学习相当曲折, 主要是因为粗心, Makefile里面的错误导致了文件生成出现各种奇奇怪怪的问题, 弄得心力交瘁, 因此制作过程还是尽量按着作者的路子来吧. 作者提供的源码的注释在中文系统下是乱码, 而且代码的分隔用了两个Tab, 在这里要处理一下: :%s/;.*//g 删除所有的注释; :%s/\t\t/\t 把两个Tab替换为一个Tab; 要让作者的nas文件和asm文件拥有相同的语法规则, 在_vimrc文件的最后一行添加 au BufNewFile,BufRead *.nas

6.30模拟赛

1.盘子序列(disk) [题目描述] 有 n 个盘子.盘子被生产出来后,被按照某种顺序摞在一起.初始盘堆中如果一 个盘子比所有它上面的盘子都大,那么它是安全的,否则它是危险的.称初始盘堆为 A,另外有一个开始为空的盘堆 B.为了掩盖失误,生产商会对盘子序列做一些“处 理”,每次进行以下操作中的一个:(1)将 A 最上面的盘子放到 B 最上面:(2)将 B 最上 面的盘子给你.在得到所有 n 个盘子之后,你需要判断初始盘堆里是否有危险的盘子. [输入格式] 输入文件包含多组数据(不超过 10 组

即刻开始使用Kotlin开发Android的12个原因(KAD 30)

作者:Antonio Leiva 时间:Jul, 11, 2017 原文链接:https://antonioleiva.com/reasons-kotlin-android/ 这组文章已到最后了,它们是非常实用的.今天我想谈谈为什么我认为学习Kotlin是非常有趣的. 虽然, Kotlin现在已是官方支持的开发Android APP的编程语言,而你仍可能觉得没有足够的理由进行改变.在这些年以来,Java已经证明其能力,为什么要改变? 这是我认为转换到Kotlin不是一个冒险的赌注,而是你可以做的

cygwin + git + nat123 30元搭建公网可访问的git服务器

首先参考上一篇安装服务器上的CYGWIN: http://jingyan.baidu.com/article/7e440953eabd742fc0e2efae.html 上一篇中已经加入了GIT相关的包,这里就不再赘述. 然后添加git用户,在CYGWIN客户端输入: net user git 123 /add 一般只是GIT用户用的话不需要加入管理员组. 随后切换windows用户,使用git用户登录,启动一次cygwin这时cygwin会自动创建用户的个人目录/home/git/以及更新其他