#打卡第一天
感受:虽然正式刷题之前有提前理解过题目,但到真正上手时还是不得不debug,还是平时练题,敲代码的细节理解存在问题。
今日收获:
一.知识点
1.数组的元素是不能删的,只能覆盖。
2.C++中二位数组位置连续,Java中二维数组位置不连续。(利用二维数组验证)
C++测试代码如下:
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
Java测试代码如下:
public static void test_arr() {
int[][] arr = {{1, 2, 3}, {3, 4, 5}, {6, 7, 8}, {9,9,9}};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
}
测试地址为:
[I@7852e922
[I@4e25154f
[I@70dea4e
[I@5c647e05
可见c++测试地址连续,Java测试地址非连续。
对此Carl哥也做出分析:(Carl哥分析Java中二维数组排列的方式。因为Java中无指针,其元素地址无法获取,方法中寻找地址只能由虚拟机完成,故只能分析预测)
二 算法题
704. 二分查找
int search(int* nums, int numsSize, int target) {
int top =0;
int las = numsSize -1;
int mid = (top + las)/2;
while(top <= las){
mid = (top + las)/2;
if(nums[mid] < target){
top = mid +1;
}
if(nums[mid] > target){
las = mid -1;
}
if(nums[mid]==target){
return mid;
}
}
printf("查找失败");
return -1;
}
分析:只写出[left,right]情况,即全闭区间情况。
左闭右开情况:
// (版本二) 左闭右开区间 [left, right)
int search(int* nums, int numsSize, int target){
int length = numsSize;
int left = 0;
int right = length; //定义target在左闭右开的区间里,即:[left, right)
int middle = 0;
while(left < right){ // left == right时,区间[left, right)属于空集,所以用 < 避免该情况
int middle = left + (right - left) / 2;
if(nums[middle] < target){
//target位于(middle , right) 中为保证集合区间的左闭右开性,可等价为[middle + 1,right)
left = middle + 1;
}else if(nums[middle] > target){
//target位于[left, middle)中
right = middle ;
}else{ // nums[middle] == target ,找到目标值target
return middle;
}
}
//未找到目标值,返回-1
return -1;
}
与情况一相比,因为right无法取到,则在while循环判断条件应改为left < right 。
27. 移除元素
https://leetcode.cn/problems/remove-element/
此题暴力尝试后未写出;
最终通过理解快慢指针完成 :
int removeElement(int* nums, int numsSize, int val){
int slow = 0;
for(int fast = 0; fast < numsSize; fast++) {
//若快指针位置的元素不等于要删除的元素
if(nums[fast] != val) {
//将其挪到慢指针指向的位置,慢指针+1
nums[slow++] = nums[fast];
}
}
//最后慢指针的大小就是新的数组的大小
return slow;
}
正确暴力解法:
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
size--; // 此时数组的大小-1
}
}
return size;
}
};