劍指Offer(數據結構與算法面試題精講)C++版——day8

劍指Offer(數據結構與算法面試題精講)C++版——day8

      • 題目一:鏈表中環的入口節點
      • 題目二:兩個鏈表的第1個重合節點
      • 題目三:反轉鏈表
      • 附錄:源碼gitee倉庫

題目一:鏈表中環的入口節點

在這里插入圖片描述
在這里插入圖片描述
????這道題的有如下三個關鍵點:
(1)判斷鏈表中是否存在環;
(2)找出環的長度;
(3)快慢指針遍歷鏈表得到相遇節點,該相遇節點即為環入口。
????首先對于環的存在性判斷,可以使用快慢指針,一開始讓front指針和end指針都指向第一個節點,接下來慢指針每次向前移動1個節點,快節點每次向前移動2個節點,這樣快指針每次都會比慢指針多走1個節點,如果鏈表中存在環,那么存在一種情況,快指針比慢指針多走k*n,其中k表示一個正整數,n為環的長度。
????接下來便是找出環的長度了,在第一次快慢指針相遇之后,讓快慢指針按照之前的方式接著向前走,最后快慢指針會第二次相遇,此時便有快指針比慢指針多走的長度就是鏈表中環長。
????最后,調整依次快慢指針的開始位置,快慢指針都設置成第一個節點,接著快指針向前走環長,然后快慢指針一起向前走,下一次相遇說明便找到了入口節點了。最終得到如下代碼:

# include <iostream>
# include <algorithm>
using namespace std;
struct linkNode {int data;linkNode * next;linkNode(int val):data(val),next(nullptr) {}
};
typedef linkNode * linkList;linkList createLinkList(int arr[],int len) {//使用空頭鏈表linkList head=new linkNode(0),q=head;for(int i=0; i<len; ++i) {linkNode * p=new linkNode(arr[i]);q->next=p;q=p;}q->next=nullptr;return head;
}void mockCircle(linkList head) {linkList p=head;linkNode * q=nullptr,*last=nullptr;while(p!=nullptr) {if(p->data==3) {q=p;}if(p->next==nullptr) {last=p;}p=p->next;}last->next=q;
}linkNode* findCircleEnter(linkList head) {linkNode *front=head->next,*end=head->next;int count=1;while(front!=nullptr&&end!=nullptr&&front!=end) {front=front->next;if(end->next) {end=end->next->next;} else {end!=nullptr;}}if(end==nullptr) {return nullptr;} else {front=front->next;end=end->next->next;while(front!=end) {front=front->next;end=end->next->next;count++;}cout<<"輸出環長:"<<count<<endl;front=head->next;end=head->next;while(count--) {end=end->next;}while(front!=end) {front=front->next;end=end->next;}return end;}
}int main() {int arr[]= {1,2,3,4,5,6};linkList head= createLinkList(arr,6);mockCircle(head);cout<<"輸出入口節點的值:"<<findCircleEnter(head)->data<<endl;return 0;
}

在這里插入圖片描述

????補充說明,實際代碼應該沒有這里長,通常算法只需要寫findCircleEnter函數,但是為了方便去模擬這個查找過程,這里根據圖例構造了帶環模擬鏈表(帶有空頭鏈表)。這里的時間復雜度也比較好,站在front的角度,一開始為了得到環的長度,只需要遍歷一次鏈表,然后找入口節點,總和來看最多遍歷兩次鏈表,因此總的時間復雜度為O(n)。

題目二:兩個鏈表的第1個重合節點

在這里插入圖片描述
在這里插入圖片描述
????依稀記得這是考研408中的一道真題,相較于前面的題目而言,這道題的難度稍顯簡單。這道題的解題關鍵在于統一起點,然后讓兩個鏈表一起向后遍歷。具體的操作步驟是,首先分別對兩個鏈表的長度進行一次統計,這樣便能清晰知曉兩個鏈表長度的差異。接著,使用兩個指針,讓它們各自指向兩個鏈表的第一個節點,此時,根據之前統計得到的鏈表長度,讓長度較長的鏈表的指針先走gap個節點。例如,若長鏈表的長度為m,短鏈表的長度為n,那么gap的值就是兩者的差值,即n-m。通過這樣的方式,使得兩個鏈表的指針處于相對統一的起始位置,以便后續的遍歷操作。基于上述思路,于是便可以得到如下的代碼來實現相應的功能。

# include <iostream>
# include <algorithm>
using namespace std;
struct linkNode {int data;linkNode * next;linkNode(int val):data(val),next(nullptr) {}
};
typedef linkNode * linkList;linkList createLinkList(int arr[],int len) {//使用空頭鏈表linkList head=new linkNode(0),q=head;for(int i=0; i<len; ++i) {linkNode * p=new linkNode(arr[i]);q->next=p;q=p;}q->next=nullptr;return head;
}
void mockCircle(linkList head1,linkList head2) {linkList p1=head1->next,p2=head2->next;linkNode * q=nullptr;while(p1!=nullptr) {if(p1->data==4) {q=p1;}p1=p1->next;}while(p2->next!=nullptr) {p2=p2->next;}p2->next=q;
}linkNode* findCommon(linkList head1,linkList head2) {int count1=0,count2=0,gap=0;linkNode * p1=head1, *p2=head2,*p=head1->next,*q=head2->next;while(p1->next) {//統計head1鏈表長度 p1=p1->next;count1++;}while(p2->next) {//統計head2鏈表長度p2=p2->next;count2++;}while(count1>count2) {//拉齊鏈表起點 p=p->next;count1--;}while(count2>count1) {q=q->next;count2--;}while(p!=q){p=p->next;q=q->next;}return q;
}int main() {int arr1[]= {1,2,3,4,5,6};int arr2[]= {7,8};linkList head1= createLinkList(arr1,6);linkList head2= createLinkList(arr2,2);mockCircle(head1,head2);cout<<"輸出公共節點對應的值:"<<findCommon(head1,head2)->data<<endl;return 0;
}

在這里插入圖片描述
????同樣的,實際編碼的時候只需要寫findCommon即可。

題目三:反轉鏈表

在這里插入圖片描述
在這里插入圖片描述

????在數據結構與算法的學習和考察中,鏈表相關的題目一直是重點內容,而本題基本上算得上是鏈表系列的必考題。因為鏈表反轉操作在實際的編程場景,如操作系統底層數據處理、圖形渲染中的節點順序調整等方面經常會被使用到。對于這道題,其解題的一個非常關鍵的思路是,將指針pre初始化為null。這樣做的目的在于為后續鏈表節點指針方向的改變提供一個起始參照。在每次循環過程中,巧妙地改變指針的指向,從而逐步實現鏈表的反轉。每一次指針方向的調整,都是對鏈表原有結構的一次重塑,通過這種循環操作,最終能夠將整個鏈表的順序反轉過來。最終得到的代碼如下:

# include <iostream>
# include <algorithm>
using namespace std;
struct linkNode {int data;linkNode * next;linkNode(int val):data(val),next(nullptr) {}
};
typedef linkNode * linkList;linkList createLinkList(int arr[],int len) {//使用空頭鏈表linkList head=new linkNode(0),q=head;for(int i=0; i<len; ++i) {linkNode * p=new linkNode(arr[i]);q->next=p;q=p;}q->next=nullptr;return head;
}void printLinkList(linkList head) {linkList p=head->next;while(p!=nullptr) {cout<<p->data<<" ";p=p->next;}
}
void reverseList(linkList head) {linkNode * pre=nullptr,*cur=head->next,*next=nullptr,*last=nullptr;while(cur) {if(!cur->next) {//因為存在空頭,所以在真實元素反轉后,需要讓頭指向最后一個節點last=cur;}next=cur->next;cur->next=pre;pre=cur;cur=next;}head->next=last;
}int main() {int arr1[]= {1,2,3,4,5};linkList head= createLinkList(arr1,5);reverseList(head);cout<<"輸出反轉之后的鏈表:";printLinkList(head);return 0;
}

在這里插入圖片描述

附錄:源碼gitee倉庫

????考慮到有些算法需要模擬數據,如果全部放進來代碼顯得過長,不利于聚焦在算法的核心思路上。于是把所有的代碼整理到了開源倉庫上,如果想要看詳細模擬數據,可在開源倉庫自取:【凌空暗羽/劍指offer-C++版手寫代碼】。

????我是【Jerry說前后端】,本系列精心挑選的算法題目全部基于經典的《劍指 Offer(數據結構與算法面試題精講)》。在如今競爭激烈的技術求職環境下,算法能力已成為前端開發崗位筆試考核的關鍵要點。通過深入鉆研這一系列算法題,大家能夠系統地積累算法知識和解題經驗。每一道題目的分析與解答過程,都像是一把鑰匙,為大家打開一扇通往高效編程思維的大門,幫助大家逐步提升自己在數據結構運用、算法設計與優化等方面的能力。
????無論是即將踏入職場的應屆畢業生,還是想要進一步提升自己技術水平的在職開發者,掌握扎實的算法知識都是提升競爭力的有力武器。希望大家能跟隨我的步伐,在這個系列中不斷學習、不斷進步,為即將到來的前端筆試做好充分準備,順利拿下心儀的工作機會!快來訂閱吧,讓我們一起開啟這段算法學習之旅!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/900824.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/900824.shtml
英文地址,請注明出處:http://en.pswp.cn/news/900824.shtml

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

相關文章

【BFT帝國】20250409更新PBFT總結

2411 2411 2411 Zhang G R, Pan F, Mao Y H, et al. Reaching Consensus in the Byzantine Empire: A Comprehensive Review of BFT Consensus Algorithms[J]. ACM COMPUTING SURVEYS, 2024,56(5).出版時間: MAY 2024 索引時間&#xff08;可被引用&#xff09;: 240412 被引:…

前端用用jsonp的方式解決跨域問題

前端用用jsonp的方式解決跨域問題 前端用用jsonp的方式解決跨域問題 前端用用jsonp的方式解決跨域問題限制與缺點&#xff1a;前端后端測試使用示例 限制與缺點&#xff1a; 不安全、只能使用get方式、后臺需要相應jsonp方式的傳參 前端 function jsonp(obj) {// 動態生成唯…

MySQL詳解最新的官方備份方式Clone Plugin

一、Clone Plugin的動態安裝 install plugin clone soname mysql_clone.so;select plugin_name,plugin_status from information_schema.plugins where plugin_name clone; 二、Clone Plugin配置持久化 在 MySQL 配置文件my.cnf中添加以下內容&#xff0c;確保插件在 MySQL …

解決python manage.py shell ModuleNotFoundError: No module named xxx

報錯如下&#xff1a; python manage.py shellTraceback (most recent call last):File "/Users/z/Documents/project/c/manage.py", line 10, in <module>execute_from_command_line(sys.argv)File "/Users/z/.virtualenvs/c/lib/python3.12/site-packa…

鴻蒙NEXT開發資源工具類(ArkTs)

import { AppUtil } from ./AppUtil; import { StrUtil } from ./StrUtil; import { resourceManager } from kit.LocalizationKit;/*** 資源工具類。* 提供訪問應用資源的能力&#xff0c;包括布爾值、數字、字符串等資源的獲取。** author 鴻蒙布道師* since 2025/04/08*/ ex…

css使用mix-blend-mode的值difference實現內容和父節點反色

1. 使用場景 往往開發過程中&#xff0c;經常遇到產品說你這個背景圖和文字顏色太接近了&#xff0c;能不能適配下背景圖&#xff0c;讓用戶能夠看清具體內容是啥。 這么說吧&#xff0c;這種需求場景非常合理&#xff0c;因為你做開發就是要給用戶一個交代&#xff0c;給他們…

el-input 中 select 方法使用報錯:屬性“select”在類型“HTMLElement”上不存在

要解決該錯誤&#xff0c;需明確指定元素類型為 HTMLInputElement&#xff0c;因為 select() 方法屬于輸入元素。 步驟解釋&#xff1a; 類型斷言&#xff1a;使用 as HTMLInputElement 將元素類型斷言為輸入元素。 可選鏈操作符&#xff1a;保持 ?. 避免元素為 null 時出錯…

Mybatis Plus與SpringBoot的集成

Mybatis Plus與SpringBoot的集成 1.引入Maven 依賴2.配置application.yml文件3.創建實體類4.分頁插件5.邏輯刪除功能6.忽略特定字段7.自動填充 1.引入Maven 依賴 提前創建好一個SpringBoot項目&#xff0c;然后在項目中引入MyBatis Plus依賴 <dependency><groupId&g…

大數據學習(104)-clickhouse與hdfs

&#x1f34b;&#x1f34b;大數據學習&#x1f34b;&#x1f34b; &#x1f525;系列專欄&#xff1a; &#x1f451;哲學語錄: 用力所能及&#xff0c;改變世界。 &#x1f496;如果覺得博主的文章還不錯的話&#xff0c;請點贊&#x1f44d;收藏??留言&#x1f4dd;支持一…

【簡歷全景認知2】電子化時代對簡歷形式的降維打擊:從A4紙到ATS的生存游戲

一、當簡歷遇上數字洪流:傳統形式的式微 在1990年代,一份排版精美的紙質簡歷還能讓HR眼前一亮;但今天,超過75%的 Fortune 500 企業使用ATS(Applicant Tracking System)進行初篩,未優化的簡歷可能在5秒內就會淪為數字廢土。這種變遷本質上符合「技術接納生命周期」理論—…

esp32cam -> 服務器 | 手機 -> 服務器 直接服務器傳輸圖片

服務器先下載python &#xff1a; 一、Python環境搭建&#xff08;CentOS/Ubuntu通用&#xff09; 一條一條執行 安裝基礎依賴 # CentOS sudo yum install gcc openssl-devel bzip2-devel libffi-devel zlib-devel # Ubuntu sudo apt update && sudo apt install b…

SeaTunnel系列之:Apache SeaTunnel編譯和安裝

Apache SeaTunnel編譯 Prepare編譯克隆源代碼本地安裝子項目從源代碼構建 SeaTunnel構建子模塊安裝 JetBrains IDEA Scala 插件安裝 JetBrains IDEA Lombok 插件代碼風格運行簡單示例不僅如此 安裝下載 SeaTunnel 發布包下載連接器插件從源代碼構建 SeaTunnel 運行 SeaTunnel 在…

JavaScript/React中,...(三個連續的點)被稱為 擴展運算符(Spread Operator) 或 剩余運算符(Rest Operator)

const processOrder (order) > {const tax order.total * 0.1;const finalAmount order.total tax;return { ...order, tax, finalAmount }; }; 解釋一下&#xff0c;特別&#xff1a;...?在JavaScript/React中&#xff0c;...&#xff08;三個連續的點&#xff09;被稱…

FRP的proxies只是建立通道,相當于建立與服務器溝通的不同通道而不是直接將路由器與服務器云端溝通

沒有更好的辦法了嗎&#xff0c;我看frpc.toml的里面可以設置兩個proxies那我esp32的監聽端口設置在frpc.toml里面它不也能跟云服務器建立聯系嗎&#xff0c;比如遠程與本地端口都配置為5112那云服務器接收到的5112訪問會以frp配置的本地端口5112轉發到frp客戶端的路由器&#…

#在docker中啟動mysql之類的容器時,沒有掛載的數據...在后期怎么把數據導出外部

如果要導出 Docker 容器內的 整個目錄&#xff08;包含所有文件及子目錄&#xff09;&#xff0c;可以使用以下幾種方法&#xff1a; 方法 1&#xff1a;使用 docker cp 直接復制目錄到宿主機 適用場景&#xff1a;容器正在運行或已停止&#xff08;但未刪除&#xff09;。 命…

Java的JDK、JRE、JVM關系與作用

Java的JDK、JRE、JVM關系與作用 java中的JDK、JRE和JVM是三個核心組件&#xff0c;各自承擔不同角色&#xff0c;且存在層級依賴關系 1. JVM&#xff08;Java Virtual Machine&#xff0c;Java虛擬機&#xff09; 是什么&#xff1a; JVM是虛擬的計算機&#xff0c;能夠執行…

C++學習之套接字并發服務器

目錄 1.昨天套接字服務器的弊端 2.如何通過多進程方式實現服務器并發 3.多進程服務器-1 4.多進程服務器-2 5.多進程版程序-回收子進程被信號中斷的處理 6.多線程版TCP服務處理思路 7.多線程并發服務器編寫 8.為什么不能把文件描述符地址傳到子線程中 9.多線程程序測試 …

機器學習新范式:Kubernetes + Kubeflow,解鎖模型訓練與部署的高效密碼

一、Kubernetes在機器學習模型訓練與部署中的作用 Kubernetes作為一個強大的容器編排平臺&#xff0c;為機器學習模型的訓練與部署提供了以下核心支持&#xff1a; 分布式訓練支持&#xff1a;Kubernetes能夠自動化部署和管理PyTorch等機器學習框架的分布式訓練任務。通過利用…

動態科技感html導航網站源碼

源碼介紹 動態科技感html導航網站源碼&#xff0c;這個設計完美呈現了科幻電影中的未來科技界面效果&#xff0c;適合展示技術類項目或作為個人作品集的入口頁面&#xff0c;自適應手機。 修改卡片中的鏈接指向你實際的HTML文件可以根據需要調整卡片內容、圖標和顏色要添加更…

數字內容智能推薦優化策略

個性化推薦算法構建路徑 構建高效數字內容體驗的推薦系統&#xff0c;需以多源數據融合為基礎框架。首先通過用戶畫像建模整合人口屬性、行為軌跡及興趣標簽&#xff0c;結合協同過濾與深度學習算法建立內容關聯矩陣。在此基礎上&#xff0c;引入上下文感知機制&#xff0c;動…