JZ-C-38

剑指offer第三十八题:数字在排序数组中出现的次数

  1 //============================================================================
  2 // Name        : JZ-C-38.cpp
  3 // Author      : Laughing_Lz
  4 // Version     :
  5 // Copyright   : All Right Reserved
  6 // Description : 数字在排序数组中出现的次数
  7 //============================================================================
  8
  9 #include <iostream>
 10 #include <stdio.h>
 11 using namespace std;
 12
 13 int GetFirstK(int* data, int length, int k, int start, int end);
 14 int GetLastK(int* data, int length, int k, int start, int end);
 15
 16 int GetNumberOfK(int* data, int length, int k) {
 17     int number = 0;
 18
 19     if (data != NULL && length > 0) {
 20         int first = GetFirstK(data, length, k, 0, length - 1);
 21         int last = GetLastK(data, length, k, 0, length - 1);
 22
 23         if (first > -1 && last > -1)
 24             number = last - first + 1;
 25     }
 26
 27     return number;
 28 }
 29
 30 // 找到数组中第一个k的下标。如果数组中不存在k,返回-1
 31 int GetFirstK(int* data, int length, int k, int start, int end) {
 32     if (start > end)
 33         return -1;
 34
 35     int middleIndex = (start + end) / 2;
 36     int middleData = data[middleIndex];
 37
 38     if (middleData == k) {
 39         if ((middleIndex > 0 && data[middleIndex - 1] != k) || middleIndex == 0)// data[middleIndex - 1] != k 以此判断是不是第一个k
 40             return middleIndex;
 41         else
 42             end = middleIndex - 1;
 43     } else if (middleData > k)
 44         end = middleIndex - 1;
 45     else
 46         start = middleIndex + 1;
 47
 48     return GetFirstK(data, length, k, start, end);
 49 }
 50
 51 // 找到数组中最后一个k的下标。如果数组中不存在k,返回-1
 52 int GetLastK(int* data, int length, int k, int start, int end) {
 53     if (start > end)
 54         return -1;
 55
 56     int middleIndex = (start + end) / 2;
 57     int middleData = data[middleIndex];
 58
 59     if (middleData == k) {
 60         if ((middleIndex < length - 1 && data[middleIndex + 1] != k)//data[middleIndex + 1] != k 以此判断是不是最后一个k
 61                 || middleIndex == length - 1)
 62             return middleIndex;
 63         else
 64             start = middleIndex + 1;
 65     } else if (middleData < k)
 66         start = middleIndex + 1;
 67     else
 68         end = middleIndex - 1;
 69
 70     return GetLastK(data, length, k, start, end);
 71 }
 72
 73 // ====================测试代码====================
 74 void Test(char* testName, int data[], int length, int k, int expected) {
 75     if (testName != NULL)
 76         printf("%s begins: ", testName);
 77
 78     int result = GetNumberOfK(data, length, k);
 79     if (result == expected)
 80         printf("Passed.\n");
 81     else
 82         printf("Failed.\n");
 83 }
 84
 85 // 查找的数字出现在数组的中间
 86 void Test1() {
 87     int data[] = { 1, 2, 3, 3, 3, 3, 4, 5 };
 88     Test("Test1", data, sizeof(data) / sizeof(int), 3, 4);
 89 }
 90
 91 // 查找的数组出现在数组的开头
 92 void Test2() {
 93     int data[] = { 3, 3, 3, 3, 4, 5 };
 94     Test("Test2", data, sizeof(data) / sizeof(int), 3, 4);
 95 }
 96
 97 // 查找的数组出现在数组的结尾
 98 void Test3() {
 99     int data[] = { 1, 2, 3, 3, 3, 3 };
100     Test("Test3", data, sizeof(data) / sizeof(int), 3, 4);
101 }
102
103 // 查找的数字不存在
104 void Test4() {
105     int data[] = { 1, 3, 3, 3, 3, 4, 5 };
106     Test("Test4", data, sizeof(data) / sizeof(int), 2, 0);
107 }
108
109 // 查找的数字比第一个数字还小,不存在
110 void Test5() {
111     int data[] = { 1, 3, 3, 3, 3, 4, 5 };
112     Test("Test5", data, sizeof(data) / sizeof(int), 0, 0);
113 }
114
115 // 查找的数字比最后一个数字还大,不存在
116 void Test6() {
117     int data[] = { 1, 3, 3, 3, 3, 4, 5 };
118     Test("Test6", data, sizeof(data) / sizeof(int), 6, 0);
119 }
120
121 // 数组中的数字从头到尾都是查找的数字
122 void Test7() {
123     int data[] = { 3, 3, 3, 3 };
124     Test("Test7", data, sizeof(data) / sizeof(int), 3, 4);
125 }
126
127 // 数组中的数字从头到尾只有一个重复的数字,不是查找的数字
128 void Test8() {
129     int data[] = { 3, 3, 3, 3 };
130     Test("Test8", data, sizeof(data) / sizeof(int), 4, 0);
131 }
132
133 // 数组中只有一个数字,是查找的数字
134 void Test9() {
135     int data[] = { 3 };
136     Test("Test9", data, sizeof(data) / sizeof(int), 3, 1);
137 }
138
139 // 数组中只有一个数字,不是查找的数字
140 void Test10() {
141     int data[] = { 3 };
142     Test("Test10", data, sizeof(data) / sizeof(int), 4, 0);
143 }
144
145 // 鲁棒性测试,数组空指针
146 void Test11() {
147     Test("Test11", NULL, 0, 0, 0);
148 }
149
150 int main(int argc, char** argv) {
151     Test1();
152     Test2();
153     Test3();
154     Test4();
155     Test5();
156     Test6();
157     Test7();
158     Test8();
159     Test9();
160     Test10();
161     Test11();
162
163     return 0;
164 }
时间: 2024-12-10 08:34:20

JZ-C-38的相关文章

算法导论 第三版 9.3-8

1 # -*- coding: utf-8 -*- 2 import math 3 4 def merge(l1, l2): 5 list_merge = [] 6 i = j = 0 7 while i < len(l1) and j < len(l2): 8 if l1[i] < l2[j]: 9 list_merge.append(l1[i]) 10 i += 1 11 else: 12 list_merge.append(l2[j]) 13 j += 1 14 if i == l

2016年9月全球桌面系统份额:Win7为39.38%,Win10达

10月1日消息,数据调研机构StatCounter目前给出了2016年9月份全球茗彩娱乐桌面系统市场份额统计排名,数据显示,Win10的增长势头依然良好,在市场份额上和目前排名第一的Win7还有15%左右的差距. 虽然微软在7月29日停止了Windows10免费更新服务,虽然此前微软在2018财年创造10亿Win10用户的目标看起来已经无法实现,但Win10推出后的整体势头依然有目共睹.根据StatCounter的数据,截止2016年9月,Win10已经占据24.46%的市场份额,而Win7为3

Win32 汇编 - 跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等

跳转指令分三类:一.无条件跳转: JMP;二.根据 CX.ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转).JECXZ(ECX 为 0 则跳转);三.根据 EFLAGS 寄存器的标志位跳转, 这个太多了. 根据标志位跳转的指令: JE ;等于则跳转 JNE ;不等于则跳转 JZ ;为 0 则跳转 JNZ ;不为 0 则跳转 JS ;为负则跳转 JNS ;不为负则跳转 JC ;进位则跳转 JNC ;不进位则跳转 JO ;溢出则跳转 JNO ;不溢出则跳转 JA ;无符号大于则跳转 JNA

leetCode 38. Count and Say 字符串

38. Count and Say The count-and-say sequence is the sequence of integers beginning as follows:1, 11, 21, 1211, 111221, ... 1 is read off as "one 1" or 11.11 is read off as "two 1s" or 21.21 is read off as "one 2, then one 1" 

Java重写《C经典100题》 --38

[程序38] 题目:求一个3*3矩阵对角线元素之和  1.程序分析:利用双重for循环控制输入二维数组,再将a[i][i]累加后输出. 2.程序源代码: 1 import java.util.Arrays; 2 import java.util.Random; 3 4 /** 5 * 6 *[程序38] 7 * 题目:求一个3*3矩阵对角线元素之和. 8 * 程序分析:利用双重for循环控制输入二维数组,再将arr[i][i]累加后输出. 9 * 10 * @author www.cnblogs

C#自学之路38

38.连接数据库和断开数据库  有两种办法连接数据库,一种是利用向导,就不做介绍了.另外就是利用代码,sql的Connetion类. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Task

centos6.5 开发环境部署(nignx1.7.10+php5.4.38+mysql)

一些命令和规则以及准备 本次流程再 DigitalOcean上的vps上通过 查看是否已经安装 rpm -qa | grep nginx 删除安装 #普通删除模式 rpm -e nginx #强力删除模式,如果使用上面命令删除时,提示有依赖的其它文件,则用该命令可以对其进行强力删除 rpm -e --nodeps nginx 查看端口是否被占用 netstat -ano|grep 80 目录 #源码 /usr/local/src #安装目录 /user/local/ 安装编译代码需要的包 yum

微信公众平台开发基础知识38问

最近接触微信公众号后台的开发,看了一些资料基本可以满足简单的需求开发.笔者将这些问题及解答整理出来,以帮助更多初学者少走弯路. 1.订阅号与服务号的主要区别是什么? 订阅号每天能群发一条消息,没有自定义菜单及高级接口权限(目前 个人.企业订阅号关联腾讯微博认证之后才有自定义菜单):服务号有自定义菜单微信认证之后有高级接口权限,但每月只能群发一条消息. 2.到底该申请订阅号还是服务号? 申请哪种类型的公众账号,主要取决于账号的用途.服务号主要面向企业和组织,旨在为用户提供服务:订阅号主要面向媒体和

38: Validate Binary Search Tree

/************************************************************************/        /*       38:      Validate Binary Search Tree                            */        /************************************************************************/        /* 

15篇干货博客 38本书 4门公开课 减掉20斤体重 我的2014总结

欢迎关注我的新博客地址:http://cuipengfei.me/ 2014年即将结束,需要做一些总结. 既然总结是写在博客上的,第一项就先说博客吧. 博客 2014年写了18篇博客,其中15篇和Scala有关,自认为都是有且仅有干货的. 对此,我比较满意. 不过这个数字存在欺骗性,15篇Scala的博客,其中4篇写于1月份,6篇写于6月份,其余的零散的写就与其他月份. 66.66-%集中地爆发于两个月里,其余十个月只贡献了总体的33.33-% 可见写博客这件事于我而言并没有形成持久的习惯,只是