簡單記錄牛客top101算法題(初級題C語言實現)BM17 二分查找 BM21 旋轉數組的最小數字 BM23 二叉樹的前序遍歷

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 hereint 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 hereif(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.pswp.cn/news/36544.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36544.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36544.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【云原生】K8S存儲卷:PV、PVC詳解

目錄 一、emptyDir存儲卷二、hostPath存儲卷三、nfs共享存儲卷四、PVC 和 PV4.1 NFS使用PV和PVC4.2創建動態PV 一、emptyDir存儲卷 容器磁盤上的文件的生命周期是短暫的&#xff0c;這就使得在容器中運行重要應用時會出現一些問題。首先&#xff0c;當容器崩潰時&#xff0c;ku…

UG NX二次開發(C++)-PK函數創建一條圓弧曲線

文章目錄 1、前言2、創建一個項目3、添加頭文件4、在do_it中添加創建圓曲線的源代碼5、調用dll6、再創建一個長方體驗證1、前言 采用PK進行UG NX二次開發,現在看到的文章很多是直接創建實體,然后在UG NX的視圖區顯示出來,對于創建圓曲線的文章不多,本文講一下PK函數創建圓…

Java基礎篇--日期時間類

目錄 前言 Instant&#xff08;時間戳&#xff09;類 LocalData(日期)類 LocalTime(時間)類 LocalDataTime(日期時間)類 Duration(時間間隔)類 Period(日期間隔)類 Clock&#xff08;獲取時區&#xff09;類 前言 在開發中經常需要處理日期和時間&#xff0c;Java提供…

Git 代碼分支規范

目的 俗話說&#xff1a;沒有規矩&#xff0c;不成方圓。遵循一個好的規章制度能讓你的工作事半功倍。同時也可以展現出你做事的認真的態度以及你的專業性&#xff0c;不會顯得雜亂無章&#xff0c;管理困難。Git分支規范也是一樣。當遵循了某種約定的Git分支&#xff0c;在代…

若依框架淺淺介紹

由若依官網所給介紹可知 1、文件結構介紹 在ruoyi-admin的pom.xml文件中引入了ruoyi-framework、ruoyi-quartz和ruoyi-generatior模塊&#xff0c;在ruoyi-framework的pom.xml文件中引入了ruoyi-system模塊。 2、技術棧介紹 前端&#xff1a;Vue、Element UI后端&#xff1a…

Redis持久化機制簡介

當涉及到Redis的持久化時&#xff0c;有兩種主要的持久化方式&#xff1a;RDB&#xff08;Redis Database&#xff09;快照和AOF&#xff08;Append-Only File&#xff09;日志。這些方式可以根據需求的不同&#xff0c;選擇適合的策略。 RDB&#xff08;Redis Database&#…

第1章:緒論

科學、技術、工程、應用 科學&#xff1a;是什么、為什么技術&#xff1a;怎么做工程&#xff1a;怎樣做的多快好省應用&#xff1a;怎么使用 定義 機器學習&#xff1a;利用經驗改善系統自身的性能。 研究 智能數據分析&#xff08;數據分析算法&#xff09; 典型的機器…

電腦ip地址怎么改 ip地址怎么改到別的城市

一、ip地址怎么改到別的城市 1.ip地址怎么改到別的城市&#xff0c;1、重啟WIFI路由設備 一般手機或電腦在家或公司上網時都是接入到路由器的WIFI網絡,再由路由器分配上網IP地址,如果要更換上網IP那么重啟路由器設備后,路由器會向網絡運營商進行寬帶的重新撥號,此時手機或電腦設…

【【verilog 典型電路設計之加法器樹乘法器】】

verilog 典型電路設計之加法器樹乘法器 加法器樹乘法器 加法器樹乘法器的設計思想是“移位后加”&#xff0c;并且加法運算采用加法器樹的形式。乘法運算的過程是&#xff0c;被乘數與乘數的每一位相乘并且乘以相應的權值&#xff0c;最后將所得的結果相加&#xff0c;便得到了…

mongodb:環境搭建

mongodb 是什么&#xff1f; MongoDB是一款為web應用程序和互聯網基礎設施設計的數據庫管理系統。沒錯MongoDB就是數據庫&#xff0c;是NoSQL類型的數據庫 為什么要用mongodb&#xff1f; &#xff08;1&#xff09;MongoDB提出的是文檔、集合的概念&#xff0c;使用BSON&am…

【Go】常見的四個內存泄漏問題

Goroutine沒有順利結束 1、這里更多的是由于channelforselect導致的&#xff0c;錯誤的寫法導致了發送者或接收者沒有發現channel已經關閉&#xff0c;任務已經結束了&#xff0c;卻仍然在嘗試輸入輸出https://geektutu.com/post/hpg-exit-goroutine.html Map的remove方法不會…

selenium.webdriver Python爬蟲教程

文章目錄 selenium安裝和使用 selenium安裝和使用 pip install selenium 下載對應的瀏覽器驅動 實例化瀏覽器 from selenium import webdriverbrowser webdriver.Chrome()元素定位 控制瀏覽器

HTB-Keeper

HTB-Keeper 信息收集80端口 lnorgaardroot 信息收集 80端口 80主頁給了一個跳轉的鏈接 跟隨鏈接后到了一個登陸界面。 嘗試搜索默認密碼。 通過賬號root:password登錄。不知道為什么我登陸了兩次才成功。 通過搜索在Admin->Users->Select里面發現了用戶信息。 lno…

WS2812B————動/靜態顯示

一&#xff0c;系統架構 二&#xff0c;芯片介紹 1.管腳說明 2.數據傳輸時間 3.時序波形 4.數據傳輸方法 5.常用電路連接 三&#xff0c;代碼展示及說明 驅動模塊 在驅動模塊首先選擇使用狀態機&#xff0c;其中包括&#xff0c;空閑狀態&#xff0c;復位清空狀態&#xff0c…

怎么把圖片表格轉換成word表格?幾個步驟達成

在處理文檔時&#xff0c;圖片表格的轉換是一個常見的需求。而手動輸入表格是非常耗時的&#xff0c;因此&#xff0c;使用文本識別軟件來自動轉換圖片表格可以大大提高工作效率。在本文中&#xff0c;我們將介紹如何使用OCR文字識別技術來將圖片表格轉換為Word表格。 OCR文字識…

Vue3+Element plus+pageHelper實現分頁

安裝element plus npm install element-plus --save引入 修改main.js&#xff1a; import { createApp } from vue import App from ./App.vue import ElementPlus from element-plus import element-plus/dist/index.cssconst app createApp(App) app.use(ElementPlus) ap…

15.3 【Linux】循環執行的例行性工作調度

相對于 at 是僅執行一次的工作&#xff0c;循環執行的例行性工作調度則是由 cron &#xff08;crond&#xff09; 這個系統服務來控制的。剛剛談過 Linux 系統上面原本就有非常多的例行性工作&#xff0c;因此這個系統服務是默認啟動的。另外&#xff0c; 由于使用者自己也可以…

棧和隊列--受限制的線性表

目錄 和隊列的定義和特點 1.1棧的定義和特點、 1.2隊列的定義和特點 1.3棧和隊列的應用 2.棧的表示和操作的實現 2.1棧的類型定義 2.2順序棧的表示和實現 2.2.1初始化 2.2.2入棧 2.2.3出棧 2.2.4取棧頂元素 2.3鏈棧的表示和實現 2.2.1初始化 2.2.2入棧 2.2.3出棧…

Java-運算符和控制語句(下)(基于c語言的補充)

輸出到控制臺 System.out.println(msg); // 輸出一個字符串, 帶換行 System.out.print(msg); // 輸出一個字符串, 不帶換行 System.out.printf(format, msg); // 格式化輸出 從鍵盤輸入 使用 Scanner 讀取字符串/整數/浮點數 首先需要導入util包 自動導入util包 這里把回車看…

如何選擇最佳的文件傳輸協議?(FTP、TFTP、Raysync)

在數字化時代&#xff0c;通過互聯網傳輸文件是一項常見的任務。因此&#xff0c;選擇適合您企業需求的文件傳輸協議非常重要。 文件傳輸協議是發送方和接收方之間的一套規則和信息。它的作用就像網絡兩端都能理解的一種語言&#xff0c;使得數據可以正確輸出并帶有正確的文件…