原题:https://leetcode.cn/problems/search-insert-position/description/
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5 输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2 输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7 输出: 4
C语言答案:
// 函数用于在已排序的数组nums中查找target,
//如果找到则返回其索引,否则返回插入位置以保持数组排序
int searchInsert(int* nums, int numsSize, int target) {
int left = 0, right = numsSize - 1, ans = numsSize;
// 初始化左右指针和答案(默认为数组末尾+1,即插入位置)
while (left <= right) { // 当左指针小于等于右指针时循环
int mid = ((right - left) >> 1) + left; // 计算中点,使用位运算提高效率
if (target <= nums[mid]) { // 如果目标值小于等于中点值
ans = mid; // 更新答案为中点位置(可能是目标值的位置,或者插入位置)
right = mid - 1; // 移动右指针到中点左侧
} else {
left = mid + 1; // 否则,移动左指针到中点右侧
}
}
return ans; // 返回最终答案
}
C++答案:
class Solution {
public:
// 定义一个公有成员函数,用于搜索插入位置
// 参数:nums为有序整数数组,target为待查找或插入的目标值
// 返回值:target在nums中的索引,如果不存在则返回应该插入的位置
int searchInsert(vector<int>& nums, int target) {
int n = nums.size(); // 获取数组nums的长度
int left = 0, right = n - 1, ans = n;
// 初始化左右指针和答案(默认为数组末尾+1,即插入位置)
// 当左指针小于等于右指针时,进行二分查找
while (left <= right) {
// 计算中点位置,使用位运算提高效率
int mid = ((right - left) >> 1) + left;
// 如果目标值小于等于中点值,说明目标值可能在中点左侧或就是中点
// 更新答案为中点位置,并将右指针左移
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
}
// 否则,目标值一定在中点右侧,将左指针右移
else {
left = mid + 1;
}
}
// 循环结束时,left指向了第一个大于target的元素位置
// 如果target存在于数组中,则ans已经被更新为target的索引
// 如果不存在,则ans保持为n,即应该插入的位置
return ans;
}
};
为什么要有class呢?什么是class?
一定要学先导知识,不然看不懂。
在C++中,class 关键字用于定义类,类是面向对象编程(OOP)的基础。类是一种用户定义的类型,它封装了数据(成员变量)和操作这些数据的方法(成员函数)。通过将数据和方法组织在一起,类提供了一种创建具有特定属性和行为的对象的方式。
如果你从代码中删除了 class 关键字,并且没有采取其他适当的替代措施,那么将会发生以下情况:
-
语法错误:首先,如果你直接删除了
class关键字而没有对代码进行其他修改,那么编译器将报告语法错误。在C++中,class关键字是定义类的必要部分,没有它,编译器无法识别你正在尝试定义一个类。 -
结构不再是类:如果你将
class关键字替换为struct(在C++中,struct和class非常相似,但默认访问级别不同——struct的默认访问级别是public,而class的默认访问级别是private),那么你的代码在语法上将是正确的,但类的行为可能会因为访问级别的改变而有所不同。然而,这并不是简单地“删除class”的情况。 -
无法封装:没有类,你就无法利用面向对象编程中的封装特性。封装是隐藏对象的属性和实现细节,仅对外暴露有限的接口的过程。没有类,你就无法定义这样的接口,也无法控制哪些数据可以被外部访问和修改。
-
无法创建对象:类是创建对象(实例)的模板。没有类,你就无法创建具有特定属性和行为的对象。
-
无法继承和多态:面向对象编程中的另外两个重要特性是继承和多态。继承允许你定义一个类的子类,子类可以继承父类的属性和方法,并可以添加或覆盖它们。多态允许你以统一的方式处理不同类型的对象。没有类,这些特性都无法实现。
-
代码结构混乱:如果你的程序完全基于过程化编程,没有使用任何类,那么随着程序规模的增大,代码可能会变得难以维护和理解。类的使用有助于将相关的数据和函数组织在一起,从而提高代码的可读性和可维护性。
总之,class 是C++中面向对象编程的基础。如果你从代码中删除了 class 关键字,并且没有采取其他适当的替代措施,那么你的程序将不再是一个面向对象的程序,而是可能退化为一个基于过程或函数的程序,这可能会限制你的程序的可扩展性、可维护性和可重用性。
关于public:
在C++中,类的成员函数(包括成员函数和成员变量)可以有不同的访问级别,这些访问级别通过关键字来指定,如public、protected和private。这些关键字决定了类的哪些部分可以被类外部的代码访问。
当你将成员函数(或成员变量)声明为public时,你是在告诉编译器这个成员函数(或成员变量)是公开的,即它可以在类的外部被访问和调用。这对于类的设计至关重要,因为它定义了类的接口——即类如何与外界交互。
对于Solution类中的searchInsert成员函数来说,它被声明为public有几个原因:
-
接口定义:
searchInsert是Solution类提供给外部使用的一个功能。通过将其声明为public,类的使用者(即其他代码)就可以调用这个函数来获取目标值在有序数组中的插入位置。 -
封装:面向对象编程(OOP)的一个基本原则是封装,即将数据(成员变量)和操作这些数据的方法(成员函数)捆绑在一起,并通过访问级别来控制对数据和方法的访问。将
searchInsert声明为public是封装过程的一部分,它允许外部代码通过预定义的接口与类交互,同时隐藏了类的内部实现细节。 -
可访问性:如果你将
searchInsert声明为private或protected,那么它就不能在类的外部被访问,这通常不是你想要的行为,除非你有一个特殊的设计需求,比如只允许在类的内部或派生类中使用这个函数。 -
符合习惯:在C++中,通常将那些需要被外部代码调用的成员函数声明为
public,这是面向对象编程的常规做法。
综上所述,将searchInsert成员函数声明为public是为了让类的使用者能够调用这个函数,从而与类进行交互,并获取所需的结果。
2569

被折叠的 条评论
为什么被折叠?



