今日学习的文章链接,或者视频链接
数组理论基础
文章链接:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
704. 二分查找
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
27. 移除元素
题目链接:https://leetcode.cn/problems/remove-element/
文章讲解:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP
自己看到题目的第一想法
- 二分查找
有两种思路,可以使用数组下标;也可以使用指针
二分查找仅适用于有序数组,可以通过 left
、right
和 mid
指向数组的元素
左闭右开 [)
、左开右闭 (]
有些没能理解题意
时间复杂度O(),空间复杂度就是数组的大小 O(n)
- 移除元素
只看题目的话感觉应该是可以用穷举法
写的时候发现还是得用双指针
看完代码随想录之后的想法
- 二分查找
确实是一看就会,一写就废
通常项目中常用的是 左闭右闭
或者 左闭右开
提到了"合法"的概念,比如 左闭右闭
,[1,1]
是合法的
两个数取中间数的方法
mid = (left + right)/2;
mid = left + (right - left)/2;
一个记忆的口诀:是闭就沾一,两闭加等于
- 删除元素
双指针的思路
快慢指针,快指针获取新数组中的元素、慢指针获取新数组中需要更新的位置
自己实现过程中遇到哪些困难
- 二分查找虽然简单,但也没能很快写出来,想着使用指针,但是写了后发现使用数组下标更方便
好久没碰代码了,最基本的语法都得考虑一下,退步太多了,还是得多敲代码啊
今日收获,记录一下自己的学习时长
- 在数组中,不要老是想着高大上的指针,有时候数组下标反而更好
code
#include <stdio.h>
/* 704. 二分查找,左闭右闭的写法,时间复杂度O(log2^n)
input:
target:目标元素
array:数组首地址
size:数组大小
output:
index:找到元素的下标
-1:没有找到元素
*/
int binarySearch(int target, int *array, int size){
int left = 0;
int right = size-1;
int mid = 0;
while(left <= right){
mid = left + (right - left)/2; // 避免越界
// mid = (left + right)/2;
if(target < *(array+mid)){
right = mid-1; // 闭合区间,如果小于或者大于的话一定不是mid
}else if(target > *(array+mid)){
left = mid+1;
}else{
return mid;
}
}
return -1;
}
/* 704. 二分查找,左闭右开的写法,时间复杂度O(log2^n)
input:
target:目标元素
array:数组首地址
size:数组大小
output:
index:找到元素的下标
-1:没有找到元素
*/
int binarySearch_other(int target, int *array, int size){
int left = 0;
int right = size; // 本来就
printf("right = %d\n", right);
int mid = 0;
while(left < right){ // [1,1) 不合法
mid = left + (right - left)/2; // 避免越界
if(target < *(array+mid)){ // 左区间
right = mid;
}else if(target > *(array+mid)){ // 右区间
left = mid+1;
}else{
return mid;
}
}
return -1;
}
/*27. 移除元素,暴力法解决,时间复杂度O(n^2)
input:
target:目标元素
array:数组首地址
size:数组大小
output:
lenNums:剩余数组的大小
*/
int myRemove(int target, int *array, int size){
for (size_t i = 0; i < size; i++){
if(target == *(array+i)){
for (size_t j = i; j < size; j++){
*(array+j) = *(array+j+1);
}
i--; // 此时该位置上的元素已经被删除了,所以需要再次判断一下
size--;
}
}
return size;
}
/*
快指针获取新数组中的元素、慢指针获取新数组中需要更新的位置
*/
int myRemove_pointer(int target, int *array, int size){
int slow = 0;
for (size_t fast = 0; fast < size; fast++){
if(target != *(array+fast)){
*(array+slow) = *(array+fast);
slow++;
}
}
return slow;
}
void showArray(int *array, int size)
{
for (size_t i = 0; i < size; i++){
printf("%d ", *(array+i));
}
printf("\n");
}
int main(int argc, char const *argv[])
{
int target = 1;
int index = 0;
int size = 0;
int array[10] = {1,1,1,3,4,5,6,7,8,9};
size = sizeof(array)/sizeof(array[0]);
#if 0
int ret = binarySearch_other(target, &array[0], size);
if(-1 == ret){
printf("not find it\n");
}else{
printf("find it, index = %d\n", ret);
}
#endif
showArray(array, size);
int count = myRemove_pointer(target, array, size);
printf("count = %d\n", count);
showArray(array, size);
return 0;
}