剑指Offer - 面试题11:旋转数组的最小数字

2023-10-26

题目

把一个数组最开始的若干个元素搬到数组末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素,例如,数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

分析

暴力法
我们不考虑任何特点,直接一次循环求解。
C

#include<stdio.h>
#include<stdlib.h>

int Min(int* n, int length)
{
	int min = INT_MAX;
	int i = 0;
	for (i = 0; i < length; i++)
	{
		if (n[i] < min)
		{
			min = n[i];
		}
	}

	return min;
}

int main()
{
	int p[5] = { 3,4,5,1,2 };
	int size = 5;
	int ret = Min(p, size);
	printf("最小值为:%d\n", ret);

	return 0;
}

二分法
我们可以将这个旋转过后的数组,分成俩个递增子数组。
在这里插入图片描述
但是还存在一种特殊情况旋转后的数组和原数组相同

在这里插入图片描述
总共有俩种情况

  • 旋转后数组与原数组不相同
  • 旋转后数组与原数组相同

设置start、end指针分别指向数组左右俩边,然后选取中间值mid = ((end - start)>>1 + start),防止溢出。
我们先选start指针做判断位置:

  • n[start] < n[mid] 在情况一中,mid位于左递增子数组,在情况二中mid位于右递增数组,所以我们换判断点

选end指针做判断位置:

  • n[end] < n[mid] 在情况一中,mid位于左递增子数组。在情况二中,不存在这种
    情况一

  • n[end] > n[mid] 在情况一中,mid位于右递增子数组。在情况二中,mid位于右递增子数组
    情况一
    情况二

  • n[end] = n[[mid] 在情况一中,mid位于右递增子数组。在情况二中,mid位于右递增子数组。
    情况一
    情况二
    C

#include<stdio.h>
#include<stdlib.h>
int Min(int* n, int length)
{
	if (n == NULL || length <= 0)
	{
		perror("");
		exit(EXIT_FAILURE);
	}
	int start = 0;
	int end = length - 1;

	while (start < end)
	{
		int mid = ((end - start) >> 1) + start;
		if (n[end] < n[mid])
		{
			start = mid + 1;
		}
		else if (n[end] > n[mid])
		{
			end = mid;
		}
		else
		{
			end--;
		}
	}
	return n[start];
}

int main()
{
	int n[10][5] = {
					{1,2,3,4,5},
					{2,3,4,5,1},
					{3,4,5,1,2},
					{4,5,1,2,3},
					{5,1,2,3,4},
					{1,1,1,2,2},
					{1,1,2,2,1},
					{1,2,2,1,1},
					{2,2,1,1,1},
					{1,1,2,2,2}, };
	int i = 0;
	for(i = 0; i< 10;i++)
	{
		int ret = Min(n[i],5);
		printf("min = %d\n", ret);
	}
	return 0;
}

在这里插入图片描述
最坏情况就是{1,1,1,1,1};相当于O(n)的时间复杂度,空间复杂度是常量O(1);
最好情况时间复杂度就是O(long2^N),空间复杂度是常量O(1);
我们也可以让n[end] = n[[mid] 相等时候直接遍历start到end 线性查找

#include<stdio.h>
#include<stdlib.h>
int Min(int* n, int length)
{
	if (n == NULL || length <= 0)
	{
		perror("");
		exit(EXIT_FAILURE);
	}
	int start = 0;
	int end = length - 1;

	while (start < end)
	{
		int mid = ((end - start) >> 1) + start;
		if (n[end] < n[mid])
		{
			start = mid + 1;
		}
		else if (n[end] > n[mid])
		{
			end = mid;
		}
		else
		{
			int m = start;//保存最小值小标
			for (++start; start < end; ++start)
			{
				if (n[m] > n[start])
				{
					m = start;
				}
			}
			return n[m];
		}
	}
	return n[start];
}

int main()
{
	int n[10][5] = {
					{1,2,3,4,5},
					{2,3,4,5,1},
					{3,4,5,1,2},
					{4,5,1,2,3},
					{5,1,2,3,4},
					{1,1,1,2,2},
					{1,1,2,2,1},
					{1,2,2,1,1},
					{2,2,1,1,1},
					{1,1,2,2,2}, };
	int i = 0;
	for(i = 0; i< 10;i++)
	{
		int ret = Min(n[i],5);
		printf("min = %d\n", ret);
	}
	return 0;
}

本章完!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

剑指Offer - 面试题11:旋转数组的最小数字 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • Dictionary的基本用法

    1 创建泛型哈希表 然后加入元素 Dictionary
  • 宋分题——Java实现登录窗口 和 信息录入窗口

    编写一个登录窗口 密码输入采用密码框 输入密码显示为 当输入用户名admin密码123的时候点击确定跳转到学生信息录入窗口界面 其他输入显示用户名密码错误 点击取消退出运行 import java awt import java awt e
  • RANSAC基本原理

    计算机视觉基本原理 RANSAC 1 RANSAC简介 2 基本思想 3 范例 4 迭代次数推导 Reference 1 计算机视觉基本原理 RANSAC 1 RANSAC简介 RANSAC RAndom SAmple Consensus
  • Ubuntu 怎么开放端口

    要在 Ubuntu 中开放端口 需要使用 ufw 防火墙 首先 确保 ufw 已经安装 如果尚未安装 可以使用以下命令进行安装 sudo apt get install ufw 然后 使用以下命令开启 ufw 防火墙 sudo ufwena
  • 玩转代码

    前言 在面试的时候 经常会遇到一道经典的面试题 如何优化网页加载速度 常规的回答中总会有一条 把 css 文件放在页面顶部 把 js 文件放在页面底部 那么 为什么要把 js 文件放在页面的最底部呢 我们先来看下这段代码
  • Android 字体加载

    1 Font配置文件 位于frameworks base data fonts system fonts xml fallback fonts xml 文件结构
  • 【LVM技术创建磁盘和磁盘配额】

    文章目录 一 知识点 二 实验 1 创建物理卷 2 卷组打包命名形成逻辑硬盘 3 创建逻辑卷 4 格式化 创建文件系统 5 挂载 三 扩容逻辑卷 四 给卷组继续添加空间 五 磁盘配额 一 知识点 LVM技术特点 1 打破分区只能单个挂载 单
  • Ubuntu下分别用gcc和makefile编译C语言

    Ubuntu下分别用gcc和makefile编译C语言 1 编写C文件 2 gcc编译C文件 3 makefile编译C文件 3 1 创建makefile文件 3 2 编译makefile文件 4 总结 在Windows环境下通过虚拟机软件
  • RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED

    问题 调用显卡时 出现RuntimeError cuDNN error CUDNN STATUS NOT INITIALIZED 问题分析 出现这种问题 一般是因为cuda cudnn 显卡驱动 torch版本不匹配造成的 解决 1 第一个
  • 【C++】IO库 : IO类,文件输入输出,string流

    前面已经在用的IO库设施 istream 输入流类型 提供输入操作 ostream 输出流类型 提供输出操作 cin 一个istream对象 从标准输入读取数据 cout 一个ostream对象 向标准输出写入数据 cerr 一个ostre
  • 为啥要三次握手,四次挥手?

    三次握手的目的是 为了防止已经失效的连接请求报文段突然又传到服务端 因而产生错误 客户端发出的第一个连接请求报文段并没有丢失 而是在某个网络结点长时间的滞留了 以致延误到连接释放以后的某个时间才到达服务器 本来这是一个早已失效的报文段 但服
  • BUUCTF[极客大挑战 2019]RCE ME

  • Qt报错undefine reference to vtable for ...解决办法

    删除编译的debug和release文件 重新编译 解决了 多方便
  • 在变量声明中指定类型

    1 内置类型 C 提供了一组标准的内置对象来表示整数 浮点数 布尔表达式 文本字符 十进制值和其他数据类型 还有内置的 string 和 object 类型 2 自定义类型 可以使用 struct class interface enum
  • UNIX网络编程卷一 学习笔记 第二十章 广播

    本书迄今为止的所有例子都是单播 一个进程与另一个进程通信 TCP只支持单播寻址 而UDP和原始IP还支持其他寻址类型 下图比较了不同的寻址方式 IPv6往寻址体系中增加了任播 anycasting 方式 RFC 1546讲述了一个IPv4任
  • sql2005 查看数据库或表大小的系统存储过程 sp_spaceused

    sql2005 查看数据库或表大小的系统存储过程 sp spaceused 语法 sp spaceused objname objname updateusage updateusage 参数 objname objname 请求其空间使用
  • 开机后电脑只剩计算机和回收站,电脑开机后C盘拒绝访问,图标只剩下此电脑和回收站是怎么回事?...

    它既然提示我们C WINDOWS system32 config systemprofile Desktop这个目录的桌面不可用 那么我们可以通过复制 桌面 文件夹到子文件里面来解决 首先我们要先找到自己当前用户名下的 桌面 后才可以复制
  • 【BP数据预测】粒子群算法优化BP神经网络数据预测(多输入多输出)【含Matlab源码 1418期】

    一 粒子群算法及BP神经网络简介 由于BP神经网络在应用过程中初始权值和阈值随机选取 容易出现局部收敛极小点 从而降低拟合效果 为了解决这个问题 采用PSO优化BP神经网络 PSO BP 算法的初始权值和阈值 解决局部极小点问题 提高BP神
  • es 时间字段聚合_es Elasticsearch 时间分组聚合查询

    正常业务逻辑中 会出现大量的数据统计 比如说分组聚合查询 根据天进行数据的统计 记录下es分组聚合查询 size 0 aggs groupDate date histogram field create date interval day
  • 剑指Offer - 面试题11:旋转数组的最小数字

    题目 把一个数组最开始的若干个元素搬到数组末尾 我们称之为数组的旋转 输入一个递增排序的数组的一个旋转 输出旋转数组的最小元素 例如 数组 3 4 5 1 2 为 1 2 3 4 5 的一个旋转 该数组的最小值为1 分析 暴力法 我们不考虑