简单记录牛客top101算法题(初级题C语言实现)BM17 二分查找 BM21 旋转数组的最小数字 BM23 二叉树的前序遍历

news2025/2/24 11:08:35

1. BM17 二分查找

   要求:给定一个 元素升序的、无重复数字的整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标(下标从 0 开始),否则返回 -1。

输入:[-1,0,3,4,6,10,13,14],13
返回值:6
说明:13     出现在nums中并且下标为6   

1.1 自己的整体思路

  1. 使用二分法,先定义三个指针,左指针,右指针,中间指针。
  2. 比较中间指针对应数值与目标数值是否相等,如果相等直接返回该点索引;如果目标值大于中间值,则移动左指针,另其为中间指针加上1;如果目标值小于中间值,则移动右指针,另其为中间指针减1。
  3. 直到左指针大于右指针,结束整个循环,这时是没有找到与目标值对应的索引的。
#include <stdbool.h>
#include <stdlib.h>
int search(int* nums, int numsLen, int target ) {
    // write code here
    int n_pre = 0;                           //首指针位置
    int n_next = numsLen - 1;                //尾部指针位置
    int n_mid = (n_pre + n_next) / 2;        //中间指针位置
    if (numsLen == 0) {                      //数组为空的情况
         return -1;
    }
    while ( nums[n_mid] != target ) {        //中间值是否等于目标值
        if ( nums[n_mid] < target) {         //目标值在中间右侧
           n_pre = n_mid + 1;                //更新左索引
           n_mid = (n_pre + n_next)/2;       //更新中间索引
        }else {
            n_next = n_mid - 1;                //更新右索引
            n_mid = (n_pre + n_next)/2;       //更新中间索引
        }
       if ( n_pre > n_next ) {                //左指针大于右指针,结束整个循环
        return -1;
    }
  }
    return n_mid;
}

  开始上面的结束条件写成了这样的了:

    if ( n_pre == n_next ) {                  //没有找到,最终两个索引会重合   会出现在右边的情况,不是一直到最后都会重合的
            if (nums[n_pre ] == target) {
                  return n_pre ;
            }else {
                  return -1;
        }
      }

  认为两个指针一定会重合,只要判断重合时候的情况就能结束整个循环,但是未通过所有的测试。

1.2 其他的方法(标准判断方法)

  判断条件是左索引是否大于右索引。

int search(int* nums, int numsLen, int target ) {
    // write code here
    if(numsLen == 0) return -1;
    int left=0, right=numsLen-1;
    while(left<=right) {
        int mid = left+(right-left)/2;
        if(nums[mid]==target) return mid;
        if(nums[mid]<target) left=mid+1;
        if(nums[mid]>target) right=mid-1;
    }
    return -1;
}

2. BM21 旋转数组的最小数字

   要求:有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

输入:[3,4,5,1,2]
返回值:1

  这个题开始使用的分类讨论的情况,情况太多了,最后也没有写出来,下面是参考大佬的写法:
核心思想:

1.计算中间位置 mid,并与 right 指针所指向的元素进行比较:
 如果 rotateArray[mid] > rotateArray[right],说明最小值在 mid 右侧,将 left 更新为 mid + 1。
 如果 rotateArray[mid] < rotateArray[right],说明最小值在 mid 左侧或就是 mid,将 right 更新为 mid。
 如果 rotateArray[mid] == rotateArray[right],无法确定最小值在哪一侧,但是可以排除 right 指针所指向的元素,将 right 向前移动一位,缩小搜索范围。
2. 循环继续,直到 left 和 right 指针相邻或重合。最终,right 指向的位置即为最小值所在位置。

int minNumberInRotateArray(int* rotateArray, int rotateArrayLen ) {
    int left=0, right=rotateArrayLen-1;
    while(left<right) {
        int mid = left+(right-left)/2;
        if(rotateArray[mid]>rotateArray[right]) left=mid+1;         //说明最小值在右边
        else if(rotateArray[mid]<rotateArray[right]) right=mid;     //说明最小值在左边
        else right--;    //22212或者10111                            //不能说明在左边还是右边,但是肯定不是右值,索引减去1再进行比较                        //关注右边,从右边出发
    }
    return rotateArray[right];
}

3. BM23 二叉树的前序遍历

   要求:给你二叉树的根节点 root ,返回它节点值的前序遍历。
                    在这里插入图片描述

输入:{1,#,2,3}
返回值:[1,2,3]

3.1 自己的整体思路

  1. 使用二叉树的前序遍历方法,递归完成二叉树元素的访问。
  2. 这里访问二叉树的元素,需要传一个变量(接收数组的索引地址),因为最后结果需要返回该索引值。

具体代码如下:

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
void visit_root(struct TreeNode* p ,int *arr, int *a){         //访问二叉树的元素,存到数组中去
    *(arr + *a) = p->val;
    //arr[*a] = p->val;    //写成这样也是可以的
    // *a++;               //这样是错的,优先级不一样,++的优先级要高
    (*a)++;          //索引加1
   }
 void  Preorder(struct TreeNode* p , int *arr, int *a){        //遍历二叉树
         if (p != NULL) {
            visit_root(p , arr, a);
            Preorder(p->left,  arr, a);    //递归左子结点         //这行代码为空的时候,才会运行到下一行
            Preorder(p->right, arr, a );   //递归右子结点
        }
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
    //前序遍历 先根,再左,再右
    struct TreeNode* cur =  root;                           //接收根结点
    int*  result = (int *)malloc(100 * sizeof(int));        //申明一个100的空数组
    int a = 0;                                              //接收数组的索引
    int *i = &a;                                            //接收a的地址
    Preorder(cur, result, i);                               //遍历二叉树 
    *returnSize = *i;                                       //必须给行号 ,卡了半天
    return result;
}

3.2 大佬的方法

  1. 先判断二叉树有多少元素,这样再动态申请多大的内存。
  2. 遍历二叉树即可。
int TreeSize(struct TreeNode* root)
{
   if(root==NULL)
   {
       return 0;
   }
    return TreeSize(root->left)+TreeSize(root->right)+1;
}
void preorder(struct TreeNode* root, int* a,int *i) 
{
    if(root==NULL)
    {
        return ;
    }
    a[*i]=root->val;
    ++(*i);
    preorder(root->left,a,i);
    preorder(root->right,a,i); 
}
int* preorderTraversal(struct TreeNode* root, int* returnSize ) 
{  
    int i=0; 
    int size=TreeSize(root);
    int* a=(int*)malloc(size*sizeof(int));
    preorder(root,a,&i);
    *returnSize=size;
    return a;
}

3.3 小结

3.3.1 malloc函数

   malloc(memory allocation)函数是用于动态分配内存的标准库函数之一。它是在程序运行时从堆(heap)中申请一块指定大小的内存空间,以供程序使用。
   malloc函数的原型如下:
size:要分配的内存空间的大小,以字节为单位。通常使用sizeof运算符来计算要分配的空间大小,以确保正确性。
返回值:malloc函数返回一个void指针,指向已分配内存块的起始地址。由于返回类型是void *,您需要将这个通用指针转换为适当类型的指针,然后才能访问和操作分配的内存。

void *malloc(size_t size);

   举例分配一个包含10个int元素的数组:

 int *array = (int *)malloc(10 * sizeof(int));

注意:

  1. malloc分配的内存块是未初始化的,其中的值是不确定的。您应该确保在使用之前将其初始化。
  2. 在使用完分配的内存后,必须使用free函数释放它,以避免内存泄漏。
  3. 在调用malloc后,应该检查返回的指针是否为NULL,以防止内存分配失败。
  4. malloc函数分配的内存是在堆上,与局部变量不同,不会在函数退出后销毁,需要手动释放。

3.3.2 *和++的优先级

++操作符的优先级比*操作符更高,因此会先执行++操作,然后再执行*操作。下面的a是一个int型变量指针
*a++;       //指针会往下加1,再去该地址里面的值,地址变了
(*a)++;     //取指针a对应的变量值,把变量值加1,地址没变

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/863174.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

栈和队列详解(1)

目录 一、什么是栈&#xff1f; 二、创建一个我们自己的栈 1.前置准备 1.1需要的三个文件 1.2结构体的创建和头文件的引用 2.接口的实现 2.1初始化栈结构体 2.2尾插(压栈) 2.3栈存放的元素个数和判断栈是否为空 2.4获取栈顶元素 2.5出栈 2.6摧毁栈 2.7测试接口 三、…

ipad触控笔有必要买原装吗?平价触控笔排行榜

“ipad好买&#xff0c;但是ipad的配件不好买”&#xff0c;我想大多数人都会遇到这样的问题&#xff0c;如果你想要购买像Apple Pencil这样的官方配件&#xff0c;有很难舍得入手&#xff0c;因为一款Apple Pencil的价格已经接近一千元了。正如很多人不会购买价格不菲的苹果官…

Falco操作系统安全威胁监测利器

原理简介 Falco是一个开源的云原生安全工具&#xff0c;用于检测和防御容器和云原生环境中的安全威胁。它基于Linux内核的eBPF技术&#xff0c;通过监控系统调用和内核事件来实现安全检测和响应。 具体来说&#xff0c;Falco的实现原理如下&#xff1a; 1. 内核模块&#xf…

「展会预告」飞凌嵌入式邀您共聚Elexcon 2023深圳国际电子展

Elexcon 2023深圳国际电子展将于8月23~25日在深圳会展中心&#xff08;福田&#xff09;隆重举行&#xff0c;飞凌嵌入式将于本届展会亮相&#xff0c;展位号1Z55。 本届展会规模达40,000平方米&#xff0c;预计将吸引600家全球优质品牌厂商、50,000专业观众齐聚现场&#xff…

登录界面中图片验证码的生成和校验

一、用pillpw生成图片验证码 1、安装pillow pip install pip install pillow2、下载字体 比如&#xff1a;Monaco.ttf 3、实现生成验证码的方法 该方法返回一个img ,可以把这个img图片保存到内存中&#xff0c;也可以以文件形式保存到磁盘&#xff0c;还返回了验证码的文字…

线上小程序电影票订单录入系统开发--Java、app、H5

在当今数字化时代&#xff0c;电影票订单的分销渠道和智能化分类已经成为电影产业不可或缺的一部分。为了满足这一需求&#xff0c;开发一款H5用户端电影票订单分销渠道智能分类小程序具有重要的实际意义。下面是该小程序开发的详细步骤。 一、需求分析 在开发H5用户端电影票…

用vim打开后中文乱码怎么办

Vim中打开文件乱码主要是文件编码问题。用户可以参考如下解决方法。 1、用vim打开.vimrc配置文件 vim ~/.vimrc**注意&#xff1a;**如果用户根目录下没有.vimrc文件就把/etc/vim/vimrc文件复制过来直接用 cp /etc/vim/vimrc ~/.vimrc2、在.vimrc中加入如下内容 set termen…

【选择排序】直接选择排序 与 堆排序

目录 1. 排序的概念&#xff1a; 2.选择排序的基本思想 3.直接选择排序 4.堆排序 1. 排序的概念&#xff1a; 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xf…

MySQL_DQL语句(查询语句以及常用函数)

基础查询 不带条件的查询查询多个字段 语法&#xff1a; #查询指定字段的数据 SELECT 字段1, 字段2, 字段3 ... FROM 表名 ; #查询表中全部字段的数据 SELECT * FROM 表名 ;案例&#xff1a;查询表中所有信息数据 SELECT * FROM employee;案例&#xff1a;查询表中姓名和性别…

IntellIJ Idea 连接数据库-MySql

前言&#xff1a;可以用mariaDB工具&#xff0c;在本地创建服务器主机和数据库&#xff0c;而后用intellIJ Idea尝试连接 MariaDB创建数据库练习 1.IntellIJ Idea打开界面右侧Database工具&#xff0c;选择MySQL数据库。 2.填写数据库账号密码&#xff0c;地址端口号&#xff…

树莓派安装Ubuntu系统(无屏幕)

树莓派安装ubuntu系统 前言 软件需要: 1.方案一 win32diskimager-1.0.0-install.exe SDFormatterha Ubuntu镜像&#xff08;可以官网下载也可以清华源&#xff09; 方案二: 树莓派镜像烧录器 树莓派镜像烧录器直达下载 硬件需要: 64GB内存卡&#xff08;推荐Sanddisk Ultra&am…

程序员自由创业周记#6:劝退

程序员自由创业周记#6&#xff1a;劝退 photo-1547496614-154dee7fd157 这是一位程序员进行独立开发创业的记录&#xff0c;将分享创业过程中的所思所想以及收支明细。 劝退 如果一位程序员问我要不要进行独立开发创业&#xff0c;我100%会建议他不要冲动&#xff0c;因为这条路…

话题暴涨2344%,“妆面减负”成大势,小红书数据发掘潮流新趋势

Less is more&#xff0c;简约风吹遍时尚界&#xff0c;小红书上继Clean fit穿搭风热度高涨后&#xff0c;Clean makeup的妆容也逐渐走红&#xff0c;成为当下年轻人争相更风的时髦新趋势。 2023时尚新趋势&#xff0c;Clean fit→Clean makeup Clean makeup&#xff0c;即轻妆…

腾讯云轻量应用服务器端口怎么打开?图文方法来了

腾讯云轻量应用服务器端口放行在哪设置&#xff1f;在防火墙中可以开启端口号&#xff0c;腾讯云轻量应用服务器端口怎么开通&#xff1f;在轻量服务器管理控制台的防火墙中开启端口&#xff0c;如果是CVM云服务器在安全组中开通&#xff0c;腾讯云服务器网以轻量应用服务器开通…

MySQL数据库-基础篇

基础篇 一、SQL 分类 DDL-数据库操作 查询 创建表 数据类型 数值类型 字符串类型 日期类型 添加 修改 删除字段 修改表名 删除表 小结 DML-数据增删改 添加数据 修改数据 删除数据 小结 DQL-数据查询数据 基本查询 条件查询 聚合函数 分组查询 排序查询 分页查…

图片转表格方法分享,几个步骤轻松转换

在日常工作和学习中&#xff0c;我们经常会遇到需要将图片中的表格转换为可编辑的电子表格的情况。这时候&#xff0c;我们通常会手动一个一个地输入表格中的数据&#xff0c;费时费力&#xff0c;还容易出错。但是&#xff0c;其实有一些简单的方法可以帮助我们快速地将图片转…

关于npoi插入一条斜向上得线记录一下

在使用hssf可以直接按照行列插入。 HSSFWorkbook book new HSSFWorkbook();HSSFSheet sheet1 (HSSFSheet)book.CreateSheet("Sheet1");HSSFPatriarch patriarch (HSSFPatriarch)sheet1.CreateDrawingPatriarch();HSSFClientAnchor a1 new HSSFClientAnchor(255, …

k8s service

1、认识Service 程序在容器中、容器在Pod中&#xff0c;可以通过pod的ip来访问应用程序&#xff0c;但是podIP会随着创建销毁而改变。由此&#xff0c;Service出现&#xff1a; Service会对提供同一个服务的多个pod进行聚合&#xff0c;并且提供一个统一的入口地址。通过访问…

摄影照片后期处理工具:Athentech Perfectly Clear Complete

Athentech Perfectly Clear Complete 是一款强悍便捷的LR图像清晰化滤镜插件&#xff0c;可以让你想要更好的处理照片&#xff0c;Perfectly Clear完美清晰掌握了智能图像校正的技术原理 &#xff0c;可以在很短的时间里创造出高质量的照片&#xff0c;所以你可以回到做你真正的…

ISO/IEC技术标准-RFID

ISO/IEC技术标准规定了RFID有关技术特征、技术参数和技术规范&#xff0c;主要包括ISO/IEC 18000(空中接口参数)、ISO/IEC 10536(密耦合、非接触集成电路卡)、ISO/IEC 15693(疏耦合、非接触集成电路卡)和ISO/IEC 14443(近耦合、非接触集成电路卡)等。ISO/IEC的RFID技术标准构成…