day01|704. 二分查找,27. 移除元素

今日学习的文章链接,或者视频链接

数组理论基础

文章链接: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

自己看到题目的第一想法

  1. 二分查找

有两种思路,可以使用数组下标;也可以使用指针
二分查找仅适用于有序数组,可以通过 leftrightmid 指向数组的元素
左闭右开 [)、左开右闭 (] 有些没能理解题意

时间复杂度O(),空间复杂度就是数组的大小 O(n)

  1. 移除元素

只看题目的话感觉应该是可以用穷举法
写的时候发现还是得用双指针

看完代码随想录之后的想法

  1. 二分查找

确实是一看就会,一写就废
通常项目中常用的是 左闭右闭 或者 左闭右开
提到了"合法"的概念,比如 左闭右闭[1,1] 是合法的
两个数取中间数的方法
mid = (left + right)/2;
mid = left + (right - left)/2;

一个记忆的口诀:是闭就沾一,两闭加等于

  1. 删除元素

双指针的思路
快慢指针,快指针获取新数组中的元素、慢指针获取新数组中需要更新的位置

自己实现过程中遇到哪些困难

  1. 二分查找虽然简单,但也没能很快写出来,想着使用指针,但是写了后发现使用数组下标更方便

好久没碰代码了,最基本的语法都得考虑一下,退步太多了,还是得多敲代码啊

今日收获,记录一下自己的学习时长

  1. 在数组中,不要老是想着高大上的指针,有时候数组下标反而更好

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值