注意数组在C++中的存储方式是在地址连续的空间中存储,所以可以通过name[n]这样的下标访问。
连续存储方便了访问,但是对于删除等操作,就需要大量移动元素,耗时较大。
C++提供了容器vetctor,也可以使用。
参考文章:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
LeetCode链接:https://leetcode.cn/problems/binary-search/
直接遍历所有元素寻找target值
// 暴力搜索
class Solution {
public:
int search(vector<int>& nums, int target) {
int n=nums.size();
for(int i=0; i<n; ++i){
if(nums[i]==target)
return i;
}
return -1;
}
};
暴力搜索可以实现, 但是时间空间复杂度过高, 下面尝试使用二分查找。
class Solution {
public:
int search(vector<int>& nums, int target) {
int n=nums.size();
int left=0, right=n-1;
while(left<=right){//注意这里是<=,因为left=right的时候也是有意义的
int middle = (left+right)/2;
if(nums[middle]==target)
return middle;
if(nums[middle]<target){
left = middle+1;
}else{
right = middle-1;
}
}
return -1;
}
};
LeetCode链接:https://leetcode.cn/problems/remove-element/
// 暴力法, 挨个遍历元素, 如果是val, 那就将其后面的元素依次前移
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n=nums.size();
int ans=n;
for(int i=0; i<ans; ){
if(nums[i]==val){
for(int j=i+1; j<ans; ++j){
nums[j-1] = nums[j];
}
--ans;
continue;
}
++i;
}
return ans;
}
};
暴力法肯定可以解决问题, 但是本题对时间复杂度要求通不过.
因为暴力法每次遇到目标值的时候, 都需要依次操作目标值后面的所有值.
但是考虑题目有暗示我们不用删除val元素, 只需要将除了val以外的元素放在数组开头, 并且返回非val值的数量即可.
所以使用双指针法:
// 双指针交换法
// 发现原题不要求输出数组的顺序和原数组一致, 所以头尾两个指针, 头指针寻找val, 找到后和尾指针swap, 尾指针--
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n=nums.size();
if(n==1){
if(nums[0]==val)
return 0;
else
return 1;
}
int head=0, tail=n-1, ans=n;
while(head<=tail){
if(nums[head]==val){
// swap(nums[head], nums[tail]);
nums[head] = nums[tail];
--tail;
--ans;
continue;
}
++head;
}
return ans;
}
};
刷题过程中要注意题目的要求和提示.
很多时候并不要求做到的一些点就可以不做到, 比如不要求顺序, 就可以乱序.
这样就可以使用一些乱七八糟的解法.
本文参考:
https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html