Day 1 千里之行始于足下~
1. 704 二分查找法
第一次提交,未使用到数组升序排序的已知条件,归结为暴力求解法,直接遍历求解
下面是二分求解法的内容:
左闭右开:
class Solution {
public:
int search(vector<int>& nums, int target) {
int iLen = nums.size();
int iRes = -1;
if(iLen == 0) return iRes;
if(iLen == 1) { return nums[0] == target? 0: -1;}
int iLeft = 0;
int iRight = iLen - 1;
while(iRight - iLeft + 1 > 2)
{
int iMid = (iRight - iLeft) / 2 + iLeft;//此处要加入偏移
if(nums[iMid] > target)
{
iRight = iMid;
}
else if(nums[iMid] < target)
{
iLeft = iMid + 1; //加1 才算左闭右开
}
else
{
iRes = iMid;
return iRes;
}
}
return nums[iLeft] == target ? iLeft : (nums[iRight] == target ? iRight : iRes);
}
};
左闭右闭:
class Solution {
public:
int search(vector<int>& nums, int target) {
int iLen = nums.size();
int iRes = -1;
if(iLen == 0) return iRes;
if(iLen == 1) { return nums[0] == target? 0: -1;}
int iLeft = 0;
int iRight = iLen - 1;
while(iRight - iLeft + 1 > 2)
{
int iMid = (iRight - iLeft) / 2 + iLeft;
if(nums[iMid] > target)
{
iRight = iMid - 1;
}
else if(nums[iMid] < target)
{
iLeft = iMid + 1;
}
else
{
iRes = iMid;
return iRes;
}
}
return nums[iLeft] == target ? iLeft : (nums[iRight] == target ? iRight : iRes);
}
};
多判断了数组0、1、2,简洁一些的代码:
左闭右闭
class Solution {
public:
int search(vector<int>& nums, int target) {
int iRight = nums.size() - 1;
int iLeft = 0;
int iRes = -1;
while(iLeft <= iRight)
{
int iMid = iLeft + (iRight - iLeft) / 2;
if(nums[iMid] < target)
{
iLeft = iMid + 1;
}
else if(nums[iMid] > target)
{
iRight = iMid - 1;
}
else
{
return iMid;
}
}
return iRes;
}
};
相关题目: 35 34 69 367
2. 27移除元素
解答:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
nums.erase(std::remove(nums.begin(), nums.end(), val), nums.end());
return nums.size();
}
};
下面是vector一些删除函数:
- erase()
接受一个迭代器或者两个迭代器,删除范围内的元素
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = std::find(v.begin(), v.end(), 3); // 查找值为3的元素
if (it != v.end()) {
v.erase(it); // 删除找到的元素
}
// v 现在包含 {1, 2, 4, 5}
- clear()
删除vector中的所有元素
std::vector<int> v = {1, 2, 3, 4, 5};
v.clear(); // 清除所有元素
// v 现在为空
- pop_back()
删除最后一个元素
std::vector<int> v = {1, 2, 3, 4, 5};
v.pop_back(); // 删除最后一个元素
// v 现在包含 {1, 2, 3, 4}
- resize()
虽然 resize 主要用于改变 std::vector 的大小,但如果你将大小减小到小于当前大小,它也会删除多余的元素。
std::vector<int> v = {1, 2, 3, 4, 5};
v.resize(3); // 删除最后两个元素
// v 现在包含 {1, 2, 3}
- 使用 swap 方法配合临时 vector:
这是一种高效删除多个元素的方法,尤其是当你不需要保留元素的顺序时。
std::vector<int> v = {1, 2, 3, 4, 5};
v.erase(std::remove(v.begin(), v.end(), 3), v.end()); // 删除所有值为3的元素
// v 现在包含 {1, 2, 4, 5}(元素的顺序可能已改变)
这里,std::remove 并没有真正删除元素,而是将不想要的元素移动到容器的末尾,并返回一个指向新逻辑末尾的迭代器。然后,你可以使用 erase 和这个迭代器来删除这些不想要的元素。
请注意,std::vector 管理其内部元素的内存,因此当你从 std::vector 中删除元素时,你不需要(也不应该)手动调用 delete。相反,std::vector 会在适当的时候自动调用析构函数并释放内存。
双指针思路:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int iLen = nums.size();
int iFast = 0;
int iSlow = 0;
for(iFast = 0;iFast < iLen; iFast++)
{
if(nums[iFast] != val)
{
nums[iSlow++] = nums[iFast];
}
}
return iSlow;
}
};