从零开始的c++之旅——map_set的使用

1.序列式容器和关联式容器
序列式容器:逻辑结构为线性序列的数据结构,两个位置之间没有紧密的关系,比如两者交换一下还是序列式的容器,例如string,vector,deque,array等。
关联式容器:逻辑结构是非线性的,两个位置之间有紧密的关联,若交换其中两者的顺序,存储结构就被破坏了,因为他其中的元素是按关键字来保存和访问的。例如map/set系列和unordered_map/unordered_set系列。
2.set系列的使用
2.1 set的模板参数
template < class T, // T就是关键字keyclass Compare = less<T>, // 传仿函数,用来控制容器的升序降序// 默认是升序排序class Alloc = allocator<T> // 空间配置器> class set;
set底层是通过红黑树实现的,因此他的增删查的时间复杂度 O(logN),迭代器的遍历为搜索树的中序遍历,遍历出来的是一个有序列表。
set的部分接口与stirng,vector较为类似,因此我们就挑一些重要的接口详细介绍。
2.2 set的构造
无参的默认构造
虽然默认构造有三个参数,但是第三个参数空间配置器我们目前阶段不涉及,默认的缺省参数即可,我们一般就是用第一个参数控制容器的存储类型和第二个参数控制容器的升降序。
explicit set (const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
set<int, less<int>> myset;
迭代器区间构造
传一段迭代器区间构造set容器。
template <class InputIterator>set (InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type& = allocator_type());
set<int, less<int>> myset(it1, it2);
拷贝构造
set (const set& x);
列表构造
类似vector的,set可以直接传一个列表进行构造,这其中经过了隐式类型转换。
set (initializer_list<value_type> il,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
set<int> myset = { 1,5,2,8,3,2 };
2.3 set的迭代器
set的迭代器是双向迭代器,有了迭代器也就说明了set支持范围for的遍历。
int main()
{set<int> myset = { 1,5,2,8,3,2 };for (auto i : myset){cout << i << " ";}return 0;
}
2.4 set的增删查
set只支持增删查不支持改,set底层是红黑树,改了数据就破坏了里面的结构
Member types
key_type -> T
value_type -> T// 单个数据插⼊,如果已经存在则插⼊失败
pair<iterator,bool> insert (const value_type& val);// 列表插⼊,已经在容器中存在的值不会插⼊
void insert (initializer_list<value_type> il);// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert (InputIterator first, InputIterator last);// 查找val,返回val所在的迭代器,没有找到返回end()
iterator find (const value_type& val);// 查找val,返回Val的个数
size_type count (const value_type& val) const;// 删除⼀个迭代器位置的值
iterator erase (const_iterator position);// 删除val,val不存在返回0,存在返回1
size_type erase (const value_type& val);// 删除⼀段迭代器区间的值
iterator erase (const_iterator first, const_iterator last);// 返回⼤于等val位置的迭代器
iterator lower_bound (const value_type& val) const;// 返回⼤于val位置的迭代器
iterator upper_bound (const value_type& val) const;// 返回容器中有几个对印的数据(set容器一般就是0/1个)
int set::cout(set x);
2.5 insert和迭代器遍历使⽤样例
int main()
{// 去重+升序排序 set<int> s;// 去重+降序排序(给⼀个⼤于的仿函数) //set<int, greater<int>> s;s.insert(5);s.insert(2);s.insert(7);s.insert(5);//set<int>::iterator it = s.begin();auto it = s.begin();while (it != s.end()){// error C3892: “it”: 不能给常量赋值 // *it = 1;cout << *it << " ";++it;}cout << endl;// 插⼊⼀段initializer_list列表值,已经存在的值插⼊失败 s.insert({ 2,8,3,9 });for (auto e : s){cout << e << " ";}cout << endl;set<string> strset = { "sort", "insert", "add" };// 遍历string⽐较ascll码⼤⼩顺序遍历的 for (auto& e : strset){cout << e << " ";}cout << endl;
}
2.6 find和erase使⽤样例
int main()
{set<int> s = { 4,2,7,2,8,5,9 };for (auto e : s){cout << e << " ";}cout << endl;// 删除最⼩值 s.erase(s.begin());for (auto e : s){cout << e << " ";}cout << endl;// 直接删除x int x;cin >> x;int num = s.erase(x);if (num == 0){cout << x << "不存在!" << endl;}for (auto e : s){cout << e << " ";}cout << endl;// 直接查找在利⽤迭代器删除x cin >> x;auto pos = s.find(x);if (pos != s.end()){s.erase(pos);}else{cout << x << "不存在!" << endl;}for (auto e : s){cout << e << " ";}cout << endl;// 算法库的查找 O(N) auto pos1 = find(s.begin(), s.end(), x);// set⾃⾝实现的查找 O(logN) auto pos2 = s.find(x);// 利⽤count间接实现快速查找 cin >> x;if (s.count(x)){cout << x << "在!" << endl;}else{cout << x << "不存在!" << endl;}return 0;
}
2.7 multiset和set的区别
最主要的区别就是multiset支持值冗余
#include<iostream>
#include<set>
using namespace std;
int main()
{// 相⽐set不同的是,multiset是排序,但是不去重 multiset<int> s = { 4,2,7,2,4,8,4,5,4,9 };auto it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;// 相⽐set不同的是,x可能会存在多个,find查找中序的第⼀个 int x;cin >> x;auto pos = s.find(x);while (pos != s.end() && *pos == x){cout << *pos << " ";++pos;}cout << endl;// 相⽐set不同的是,count会返回x的实际个数 cout << s.count(x) << endl;// 相⽐set不同的是,erase给值时会删除所有的x s.erase(x);for (auto e : s){cout << e << " ";}cout << endl;return 0;
}
2.8 set的实际算法应用 
以往做这道环形链表的题时,我们需要使用快慢指针,最后判断两个指针是否相遇,但现在只需要一个指针,遍历这个链表依次吧链表的节点的值加入set容器中,每次加入set容器时先判断但钱节点的值是否已经在set容器中即可。
class Solution {
public:ListNode *detectCycle(ListNode *head) {set<ListNode*> s;ListNode* cur = head;while(cur){if(s.count(cur)return cur;elses.insert(cur);cur=cur->next;}return nullptr;}
};
3.map系列的使用
3.1 map的模板参数
template < class Key, // map::key_typeclass T, // map::mapped_typeclass Compare = less<Key>, // map::key_compareclass Alloc = allocator<pair<const Key,T> > // map::allocator_type > class map;
其中Key就是map底层关键字的类型,T是map底层value的类型,set默认要求Key⽀持⼩于⽐较,果不⽀持或者需要的话可以⾃⾏实现仿函数传给第⼆个模版参数。第四个参数与set相同,我们目前阶段不用管。
map底层是也是⽤红⿊树实 现,所以其增删查改效率是O(logN) ,往其中数据类型为pair类型,这个pair类型有“ key ” 和 “ value ”两个值(接下来一点我们会讲),插入到map中是按key值的大小排序的,插入逻辑与二叉树相同。
其迭代器遍历是⾛的中序,按key的值进行遍历的。
3.2 pair类型的介绍
map底层节点中插入的数据,是使用 pair<Key,T> 键值对来存储数据的。
typedef pair<const Key, T> value_type;
template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair(): first(T1()), second(T2()){}pair(const T1& a, const T2& b): first(a), second(b){}template<class U, class V> pair (const pair<U,V>& pr): first(pr.first), second(pr.second){}
};template <class T1,class T2>
inline pair<T1,T2> make_pair (T1 x, T2 y)
{return ( pair<T1,T2>(x,y) );
}
我们使用map的最爽的插入方式就是走隐式类型转换
int main()
{map<int, string> mymap;mymap.insert({ 1, "+" });mymap.insert({ 4, "-" });mymap.insert({ 2, "*" });mymap.insert({ 3, "/" });
}
3.3 map的构造
map与set又比较类似,所以这里我们简略提一提
(1) ⽆参默认构造
explicit map(const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());(2) 迭代器区间构造
template <class InputIterator>
map(InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type & = allocator_type());(3) 拷⻉构造
map(const map& x);(4) initializer 列表构造
map(initializer_list<value_type> il,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());
3.4 map的迭代器
// 迭代器是⼀个双向迭代器
iterator -> a bidirectional iterator to const value_type// 正向迭代器
iterator begin();
iterator end();
// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();
int main()
{map<int, string> mymap;mymap.insert({ 1, "+" });mymap.insert({ 4, "-" });mymap.insert({ 2, "*" });mymap.insert({ 3, "/" });for (auto i : mymap){cout << i.second << " ";}cout << endl;
}
3.5 map的增删查
map支持增删查,因为map的底层也是红黑树,改了数据就破坏了里面的结构
Member types
key_type -> Key
mapped_type -> T
value_type -> pair<const key_type,mapped_type>// 单个数据插⼊,如果已经key存在则插⼊失败,key存在相等value不相等也会插⼊失败
pair<iterator,bool> insert (const value_type& val);// 列表插⼊,已经在容器中存在的值不会插⼊
void insert (initializer_list<value_type> il);// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert (InputIterator first, InputIterator last);// 查找k,返回k所在的迭代器,没有找到返回end()
iterator find (const key_type& k);// 查找k,返回k的个数
size_type count (const key_type& k) const;// 删除⼀个迭代器位置的值
iterator erase (const_iterator position);// 删除k,k存在返回0,存在返回1
size_type erase (const key_type& k);// 删除⼀段迭代器区间的值
iterator erase (const_iterator first, const_iterator last);// 返回⼤于等k位置的迭代器
iterator lower_bound (const key_type& k);// 返回⼤于k位置的迭代器
const_iterator lower_bound (const key_type& k) const;
3.6 map的数据修改
而由于map的底层存储的是我们所说的pair<const Key, T>类型的数据,我们可以发现key的值是带了const的,这是因为我们map的底层排序是按照ket值进行的排序,因此我们无法修改key值,但是我们可以修改其T的值。
我们可以记其理解为键名和键值,键名是无法改动的,而键值是可以修改的。
map中数据的第一种修改方式是通过迭代器遍历找到对应的数据进行修改。
但是map还有一种非常重要的修改数据的方式,也就是其重载的 opreator[ ] ,operator[ ]不仅仅⽀持修改,还⽀持插⼊数据和查找数 据,所以他是⼀个多功能复合接⼝。
operator[ ] 的实现是通过map的成员函数 insert 来实现的。
为什么要通过insert函数来实现呢,因为insert函数是插入一个pait< key , T >的对象,此时就有两种情况:
1. 如果key已经在map中,那么则插入失败,返回一个pair< iterator , bool >对象,iterator指的是map中已有的该对象的节点的迭代器,bool值为false,表示插入失败,因为map中已经存在对应的键值。
2. 如果key不在map中,插入成功,返回一个pair< iterator , bool >对象,iterator指的是map中若插入的该节点的迭代器,bool值为true,表示插成功,
也就是说物理插入成功还是失败,返回的pair类型其 iterator 都是key所在的迭代器位置,那么也就意味着插入失败的情况实际是在进行查找的概念,插入成功则是实现插入的功能,这也就实现了operator所需的多功能复合借口。
Member types
key_type -> Key
mapped_type -> T
value_type -> pair<const key_type,mapped_type>mapped_type& operator[] (const key_type& k)
{pair<iterator, bool> ret = insert({ k, mapped_type() });//插入成功,pair对应的为插入到节点的位置,实现了插入的功能//插入失败,pair对应的为已有的节点的位置,实现了查找功能//而无论是哪种功能,由于返回值是其 T类型的引用,因此支持了修改的功能iterator it = ret.first;return it->second;
}
3.7 构造遍历及增删查使⽤样例
#include<iostream>
#include<map>
using namespace std;
int main()
{map<string, string> dict = { {"left", "左边"}, {"right", "右边"},{"insert", "插入"},{ "string", "字符串" } };auto it = dict.begin();while (it != dict.end()){cout << it->first << ":" << it->second << endl;++it;}cout << endl;pair<string, string> kv1("first", "第一个");//多种插入方式dict.insert(kv1);dict.insert(pair<string, string>("second", "第二个"));dict.insert(make_pair("sort", "排序"));dict.insert({ "auto", "自动的" });//这一种用着最香dict.insert({ "left", "左边,剩余" });for (const auto& e : dict){cout << e.first << ":" << e.second << endl;}cout << endl;string str;while (cin >> str){auto ret = dict.find(str);if (ret != dict.end()){cout << "->" << ret->second << endl;}else{cout << "⽆此单词,请重新输⼊" << endl;}}return 0;
}
3.8 map的迭代器和[]功能样例
#include<iostream>
#include<vector>
#include<set>
#include <map>
using namespace std;int main()
{// 利⽤[]插⼊+修改功能,巧妙实现统计⽔果出现的次数 string arr[] = { "苹果", "西⽠", "苹果", "西⽠", "苹果", "苹果", "西⽠","苹果", "⾹蕉", "苹果", "⾹蕉" };map<string, int> countMap;for (const auto& str : arr){// []先查找⽔果在不在map中 // 1、不在,说明⽔果第⼀次出现,则插⼊{⽔果, 0},同时返回次数的引⽤,// ++⼀下就变成1次了// 2、在,则返回⽔果对应的次数++ countMap[str]++;}for (const auto& e : countMap){cout << e.first << ":" << e.second << endl;}cout << endl;return 0;
}
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{map<string, string> dict;dict.insert(make_pair("sort", "排序"));// key不存在->插⼊ {"insert", string()} dict["insert"];// 插⼊+修改 dict["left"] = "左边";// 修改 dict["left"] = "左边、剩余";// key存在->查找 cout << dict["left"] << endl;return 0;
}
3.9 multimap和map的差异
类比multiset和set的区别,multimap和map的使⽤基本完全类似,主要区别点在于multimap⽀持关键值key冗余,那么 insert/find/count/erase都围绕着⽀持关键值key冗余有所差异,这⾥跟set和multiset完全⼀样,⽐如 find时,有多个key,返回中序第⼀个。
其次就是multimap不⽀持[],因为⽀持key冗余, []就只能⽀持插⼊了,不能⽀持修改。
相关文章:

从零开始的c++之旅——map_set的使用
1.序列式容器和关联式容器 序列式容器:逻辑结构为线性序列的数据结构,两个位置之间没有紧密的关系,比如两者交换一下还是序列式的容器,例如string,vector,deque,array等。 关联式容器࿱…...
Docker中的一些常用命令
find / -type f -name “文件名” 2>/dev/null 寻找所有目录中的这个文件 pwd 查看当前目录的地址 docker pull 镜像名 强制拉镜像 docker run 运行docker systemctl daemon-reload 关闭docker systemctl start docker 启动docker systemctl restart docker 重启docker /…...

自存 sql常见语句和实际应用
关于连表 查询两个表 SELECT * FROM study_article JOIN study_article_review 查询的就是两个表相乘,结果为两个表的笛卡尔积 相这样 这种并不是我们想要的结果 通常会添加一些查询条件 SELECT * FROM study_articleJOIN study_article_review ON study_art…...
python | argparse模块在命令行的使用中的重要作用
import argparseclass TestCases:def __init__(self, nameNone, expect_resultNone):self.name nameself.expect expect_resultself.parser argparse.ArgumentParser() # 创建命令解析器self.add_arguments() # 方法 : 添加命令self.args, _ self.parser.par…...

【HCIP]——OSPF综合实验
题目 实验需求 根据上图可得,实验需求为: 1.R5作为ISP:其上只能配置IP地址;R4作为企业边界路由器,出口公网地址需要通过PPP协议获取,并进行CHAP认证。(PS:因PPP协议尚未学习&#…...

PW系列工控电脑复制机:效率与精度双重提升
工控电脑复制应用:效率与精度的双重提升 随着现代企业对大数据、数据备份、和跨平台兼容性需求的快速增长,工控电脑已成为数据密集型产业的核心设备。针对工控环境中大量数据复制的特殊需求,PW系列NVMe/SATA PCIe SSD复制机(如PW…...

学习QT第二天
QT6示例运行 运行一个Widgets程序运行一个QT Quick示例 工作太忙了,难得抽空学点东西。-_-||| 博客中有错误的地方,请各位道友及时指正,感谢! 运行一个Widgets程序 在QT Creator的欢迎界面中,点击左侧的示例…...
11.20作业
题目一: 题目: // 数组的行列转置 代码: // 数组的行列转置 #include <stdio.h> int main() {int a[2][3], i, j, b[3][2];printf("输入一个两行三列的数组a:\n");for (i 0; i < 2; i)for (j 0; j < 3; j){scanf…...

Ubuntu Linux使用前准备动作_使用root登录图形化界面
Ubuntu默认是不允许使用 root 登录图形化界面的。这是出于安全考虑的设置。但如果有需要,可以通过以下步骤来实现使用 root 登录: 1、设置 root 密码 打开终端,使用当前的管理员账户登录系统。在终端中输入命令sudo passwd root,…...

DICOM核心概念:显式 VR(Explicit VR)与隐式 VR(Implicit VR)在DICOM中的定义与区别
在DICOM(Digital Imaging and Communications in Medicine)标准中,VR(Value Representation) 表示数据元素的值的类型和格式。理解显式 VR(Explicit VR)与隐式 VR(Implicit VR&#…...
源码分析Spring Boot (v3.3.0)
. ____ _ __ _ _/\\ / ____ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | _ | _| | _ \/ _ | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) ) |____| .__|_| |_|_| |_\__, | / / / /|_||___//_/_/_/:: Spring Boot :: (v3.3.0)//笔记背…...

IPv6 NDP 记录
NDP(Neighbor Discovery Protocol,邻居发现协议) 是 IPv6 的一个关键协议,它组合了 IPv4 中的 ARP、ICMP 路由器发现和 ICMP 重定向等协议,并对它们作出了改进。该协议使用 ICMPv6 协议实现,作为 IPv6 的基…...
linux常用命令(文件操作)
目录 1. ls - 列出目录内容 2. cd - 更改目录 3. pwd - 打印当前工作目录 4. mkdir - 创建目录 5. rm - 删除文件或目录 6. cp - 复制文件或目录 7. mv - 移动或重命名文件 8. touch - 更新文件访问和修改时间 9. cat - 显示文件内容 10. grep - 搜索文本 11. chmod…...

内存管理 I(内存管理的基本原理和要求、连续分配管理方式)
一、内存管理的基本原理和要求 内存管理(Memory Management)是操作系统设计中最重要和最复杂的内容之一。虽然计算机硬件技术一直在飞速发展,内存容量也在不断增大,但仍然不可能将所有用户进程和系统所需要的全部程序与数据放入主…...

【Redis】基于Redis实现秒杀功能
业务的流程大概就是,先判断优惠卷是否过期,然后判断是否有库存,最好进行扣减库存,加入全局唯一id,然后生成订单。 一、超卖问题 真是的场景下可能会有超卖问题,比如开200个线程进行抢购,抢100个…...
Hadoop 使用过程中 15 个常见问题的详细描述、解决方案
目录 问题 1:配置文件路径错误问题描述解决方案Python 实现 问题 2:YARN 资源配置不足问题描述解决方案Python 实现 问题 3:DataNode 无法启动问题描述解决方案Python 实现 问题 4:NameNode 格式化失败问题描述解决方案Python 实现…...

【Flutter 问题系列第 84 篇】如何清除指定网络图片的缓存
这是【Flutter 问题系列第 84 篇】,如果觉得有用的话,欢迎关注专栏。 博文当前所用 Flutter SDK:3.24.3、Dart SDK:3.5.3,网络图片缓存用的插件 cached_network_image: 3.4.1,缓存的网络图像的存储和检索用…...

【UE5】使用基元数据对材质传参,从而避免新建材质实例
在项目中,经常会遇到这样的需求:多个模型(例如 100 个)使用相同的材质,但每个模型需要不同的参数设置,比如不同的颜色或随机种子等。 在这种情况下,创建 100 个实例材质不是最佳选择。正确的做…...

鸿蒙动画开发07——粒子动画
1、概 述 粒子动画是在一定范围内随机生成的大量粒子产生运动而组成的动画。 动画元素是一个个粒子,这些粒子可以是圆点、图片。我们可以通过对粒子在颜色、透明度、大小、速度、加速度、自旋角度等维度变化做动画,来营造一种氛围感,比如下…...

IDEA2023 创建SpringBoot项目(一)
一、Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。 二、快速开发 1.打开IDEA选择 File->New->Project 2、…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...