赞
踩
文档讲解 : 代码随想录 - 数组理论基础
状态:再次回顾。
记录重点
验证数组连续性代码
void test_arr() {
int array[2][3] = {
{0, 1, 2},
{3, 4, 5}
};
cout << &array[0][0] << " " << &array[0][1] << " " << &array[0][2] << endl;
cout << &array[1][0] << " " << &array[1][1] << " " << &array[1][2] << endl;
}
int main() {
test_arr();
}
测试地址为
0x7ffee4065820 0x7ffee4065824 0x7ffee4065828
0x7ffee406582c 0x7ffee4065830 0x7ffee4065834
其他知识
C++基本数据类型所占的内存空间:
类型 | 32位系统 | 64位系统 |
---|---|---|
bool | 1 | 1 |
char | 1 | 1 |
short | 2 | 2 |
int | 4 | 4 |
long | 4 | 4 |
double | 8 | 8 |
float | 4 | 4 |
* | 4 | 8 |
文档讲解 : 代码随想录 - 704. 二分查找
状态:再次回顾,但是需要一段时间,问题:left = middle + 1时忘记 +1。
二分法前提条件
二分法重点
想清楚区间定义,保持区间不变量
区间定义
左闭右闭代码(ACM) [left, right]
#include <iostream> #include <vector> using namespace std; int search(vector<int>& nums, int target) { int left = 0; int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right] while (left <= right) { // 当left == right, 区间[left, right]依然有效,所以用 <= int middle = left + (right - left) / 2; // 防止溢出,等同于(left + right) / 2 if (nums[middle] > target) { right = middle - 1; // target 在左区间, 所以[left, middle - 1] } else if (nums[middle] < target) { left = middle + 1; // 易错点,无论是左闭右闭还是左闭右开,target都在右区间, 所以[middle + 1, right] } else return middle; // nums[middle] == target,数组中找到目标值,直接返回下标 } return -1; } int main() { /* 输入描述: 第一行一个整数,表示nums数组长度 第二行n个数,第i个数表示nums[i] 第三行一个整数,表示target */ int n; cin >> n; vector <int> nums(n); int target; for (int i = 0; i < n; i++) cin >> nums[i]; cin >> target; cout << search(nums, target); return 0; }
左闭右开 (ACM) [left, right)
#include <iostream> #include <vector> using namespace std; int search(vector<int>& nums, int target) { int left = 0; int right = nums.size(); // 定义target在左闭右开的区间里,[left, right) while (left < right) { // 当left == right, 区间[left, right)是无效的空间,所以用 < int middle = left + (right - left) / 2; // 防止溢出,等同于(left + right) / 2 if (nums[middle] > target) { right = middle; // target 在左区间, 所以在[left, middle)中 } else if (nums[middle] < target) { left = middle + 1; // 易错点,无论是左闭右闭还是左闭右开,target都在右区间, 所以在[middle + 1, right)中 } else return middle; // nums[middle] == target,数组中找到目标值,直接返回下标 } return -1; } int main() { /* 输入描述: 第一行一个整数,表示nums数组长度 第二行n个数,第i个数表示nums[i] 第三行一个整数,表示target */ int n; cin >> n; vector <int> nums(n); int target; for (int i = 0; i < n; i++) cin >> nums[i]; cin >> target; cout << search(nums, target); return 0; }
总结
注意自己使用的是什么区间,在循环中坚持根据查找区间的定义来做边界处理,就是循环不变量规则。
文档讲解 : 代码随想录 - 27. 移除元素
状态:再次回顾。
验证前文所说数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
本题是双指针入门经典题目,需要多次进行思考和练习。
双指针法
双指针法 (快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
本题删除过程如下:
本题代码(ACM)
#include <iostream> #include <vector> using namespace std; int removeElement(vector <int>& nums, int val){ int slowIndex = 0; for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) { if (nums[fastIndex] != val) { nums[slowIndex++] = nums[fastIndex]; // 注意fastIndex++已经在for循环内完成,是先赋值然后再++ } } return slowIndex; } int main() { /* 输入描述: 第一行一个整数,表示nums数组长度 第二行n个整数,第i个数表示nums[i] 第三行一个整数,表示移除元素val */ int n; cin >> n; vector<int> nums(n); int val; for (int i = 0; i < n; i++) cin >> nums[i]; cin >> val; cout << removeElement(nums, val) << endl; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。