704. 二分查找
题目链接:https://leetcode.cn/problems/binary-search/
int search(int* nums, int numsSize, int target) {
int left=0;
int right=numsSize-1;
while(left<=right){
int mid=(left +right )/2;
if(nums[mid]==target ){
return mid;
}
else if(nums[mid]>target){
right=mid-1;
}
else if(nums[mid]<target){
left=mid+1;
}
}
return -1;
}
学习反思
看完讲解才意识到区间的问题,我以前都是用举例子的方式来写,相对来说耗费时间更多,但是按这种分完后会快很多。
-
第一种--左闭右闭区间
思考:
-
假设在
nums = [0, 1, 2,]
中查找1。由于是左闭右闭区间,需要包含 0 与 2 [0, 2],因此 left 指针为 0,right 指针为 2, 即为len(nums) - 1. -
在 while 循环中,若查找到 [1, 1],left == right 是可以满足区间定义的,因此
while left <= right
。当进行if else的判断的时候,mid就会已经被判断了,此时直接都进行 +1 或者 -1的操作即可。
-
-
第二种--左闭右开区间
思考:
- 同样假设在
nums = [0, 1, 2, ]
中查找1。由于是左闭右开区间,需要包含 0 与 2 [0, 3) ,因此 left 指针为 0,right 指针为 3, 即为len(nums). - 在 while 循环中,若查找到 [1, 1),等于1又小于1是矛盾的,无法满足区间定义,因此
while(left < right)
。当进行if else的判断的时候,mid一般根据写法指向中间偏左的位置,比如首先指向1。判断之后对于左边来说是[0, 1),对于1右边来说是[2, 3),所以left = mid + 1,right = mid。
- 同样假设在
根据第二种思路写出的代码
int search(int* nums, int numsSize, int target) {
int left=0;
int right=numsSize;
while(left<right){
int mid=(left +right )/2;
if(nums[mid]==target ){
return mid;
}
else if(nums[mid]>target){
right=mid;
}
else if(nums[mid]<target){
left=mid+1;
}
}
return -1;
}
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
我的解题思路
1.暴力解法(不做解释)
int removeElement(int* nums, int numsSize, int val) {
int i = 0;
int j = 0;
while (i < numsSize) {
if (nums[i] != val) {
nums[j] = nums[i];
j++;
}
i++;
}
return j;
}
2.快慢指针
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针
- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 慢指针:指向更新 新数组下标的位置
int removeElement(int* nums, int numsSize, int val) {
int slow=0;
for(int fast=0;fast<numsSize;fast++){
if(nums[fast]!= val){
nums[slow++]=nums[fast];
}
}
return slow;
}
学习反思
虽然知道双指针法(快慢指针法)在数组和链表的操作中是非常常见的,但这道题还是没有办法立刻想到这种思路。
977.有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
我的解题思路
1.暴力解法(但其实根据时间复杂度要求暴力解法是不符合的,但我最先想到的是暴力解法)
//先算出每个的平方
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
int* result = (int*)malloc(sizeof(int) * numsSize);
*returnSize = numsSize;
for (int i = 0; i < numsSize; i++) {
result[i] = nums[i] * nums[i];
}
bubbleSort(result, numsSize);
return result;
}
//再用冒泡排序
void bubbleSort(int* arr, int n) {
int i, j, temp;
for (i = 0; i < n-1; i++) {
for (j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
2.双指针法
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
*returnSize = numsSize;
int* result = (int*)malloc(sizeof(int) * numsSize);
int left = 0, right = numsSize - 1, index = numsSize - 1;
while (left <= right) {
int leftSquare = nums[left] * nums[left];
int rightSquare = nums[right] * nums[right];
if (leftSquare > rightSquare) {
result[index] = leftSquare;
left++;
} else {
result[index] = rightSquare;
right--;
}
index--;
}
return result;
}
学习反思
对双指针法更加熟练了。
总结
第一次写博客,花费了较长时间,但是感觉写完以后脑海中的知识更具象化了,记忆更清晰了,希望能在之后的过程中坚持下去!!!