數據結構——線性表(鏈表,力扣中等篇,增刪查改)

文章目錄

  • 一、增刪查改
    • 1.1增(插入節點)
      • 1.1.1兩數后插入公約數
      • 1.1.2循環有序鏈表的插入
    • 1.2刪(移除節點)
      • 1.2.1刪除已知的node節點【交換val值】
      • 1.2.2移除數組中已存在的節點【unordered_set】
      • 1.2.3刪除和為0的節點【前綴和】
    • 1.3改(交換節點)
      • 1.3.1鏈表中的下一個最大節點
      • 1.3.2刪除右側有一個更大數值的節點
      • 1.3.3交換K和倒數第K個節點
      • 1.3.4合并0之間的節點
    • 1.4其他
      • 1.4.1鏈表組件
      • 1.4.2螺旋矩陣
      • 1.4.3臨界值的距離

一、增刪查改

1.1增(插入節點)

序號題目鏈接
1兩數后插入公約數https://leetcode.cn/problems/insert-greatest-common-divisors-in-linked-list/description/?envType=problem-list-v2&envId=linked-list
2循環有序鏈表的插入https://leetcode.cn/problems/4ueAj6/description/?envType=problem-list-v2&envId=linked-list

1.1.1兩數后插入公約數

在兩個數A和B的中間插入A和B的公約數【公約數的值可以用gcd直接求】

//求最大公約數gcd
ListNode* insertGreatestCommonDivisors(ListNode* head) {if(head==nullptr || head->next==nullptr)return head;ListNode* p=head;while(p->next!=nullptr){ListNode* node=new ListNode(gcd(p->val,p->next->val));node->next=p->next;p->next=node;p=p->next->next;}return head;
}

1.1.2循環有序鏈表的插入

給定循環單調非遞減列表中的一個點,寫一個函數向這個列表中插入一個新元素 insertVal ,使這個列表仍然是循環升序的。
在這里插入圖片描述

Node* insert(Node* head, int insertVal) {Node* node=new Node(insertVal);//創建新節點if(head==nullptr){node->next=node;return node;}if(head->next==head){head->next=node;node->next=head;return head;}Node* cur=head;Node* next=head->next;while(next != head){if(cur->val <= insertVal && insertVal <= next->val) break;if((cur->val > next->val) && (insertVal >= cur->val || insertVal <= next->val) )  break;cur=cur->next;next=next->next;}node->next=next;cur->next=node;return head;
}

1.2刪(移除節點)

序號題目鏈接
1刪除鏈表中值為val的節點(簡單)https://leetcode.cn/problems/remove-linked-list-elements/description/?envType=problem-list-v2&envId=linked-list
2刪除已知的node節點https://leetcode.cn/problems/delete-node-in-a-linked-list/description/?envType=problem-list-v2&envId=linked-list
3移除鏈表中數組已存在的元素https://leetcode.cn/problems/delete-nodes-from-linked-list-present-in-array/?envType=problem-list-v2&envId=linked-list
4刪除和為0的連續節點https://leetcode.cn/problems/remove-zero-sum-consecutive-nodes-from-linked-list/description/?envType=problem-list-v2&envId=linked-list

1.2.1刪除已知的node節點【交換val值】

void deleteNode(ListNode* node) {//將node和后面的節點換個位置,然后刪除int val=node->val;//暫存節點信息node->val=node->next->val;node->next->val=val;//刪除node->next即可node->next=node->next->next;
}

1.2.2移除數組中已存在的節點【unordered_set】

ListNode* modifiedList(vector<int>& nums, ListNode* head) {ListNode* dummy=new ListNode(-1,head);unordered_set<int> s(nums.begin(),nums.end());ListNode* pre=dummy;ListNode* cur=dummy->next;while(cur!=nullptr){if(s.count(cur->val)){pre->next=cur->next;cur = pre->next;}else{cur=cur->next;pre=pre->next;}}return dummy->next;
}

1.2.3刪除和為0的節點【前綴和】

前綴和的原理:
在這里插入圖片描述
反復刪去鏈表中由 總和值為0連續節點組成的序列,直到不存在這樣的序列為止。
在這里插入圖片描述

ListNode* removeZeroSumSublists(ListNode* head) {ListNode* dummy=new ListNode(0,head);//哈希表存儲前綴和,以及最后出現的節點unordered_map<int,ListNode*> mp;int prefixsum=0;ListNode* p=dummy;while(p!=nullptr){prefixsum += p->val;mp[prefixsum]=p;// 相同前綴和會覆蓋,保留最后一個p=p->next;}//第二次遍歷prefixsum=0;p=dummy;while(p!=nullptr){prefixsum+=p->val;p->next=mp[prefixsum]->next;p=p->next;}return dummy->next;
}

1.3改(交換節點)

序號題目鏈接
1鏈表中的下一個最大節點https://leetcode.cn/problems/next-greater-node-in-linked-list/description/?envType=problem-list-v2&envId=linked-list
2刪除右側有一個更大數值的節點https://leetcode.cn/problems/remove-nodes-from-linked-list/?envType=problem-list-v2&envId=linked-list
3交換K和倒數第K個節點https://leetcode.cn/problems/swapping-nodes-in-a-linked-list/description/?envType=problem-list-v2&envId=linked-list
4合并0之間的節點https://leetcode.cn/problems/merge-nodes-in-between-zeros/description/?envType=problem-list-v2&envId=linked-list

1.3.1鏈表中的下一個最大節點

遍歷整個鏈表,找到第一個比當前值大的元素。沒有則為0。

解法1:

  • p指向當前節點
  • q指向當前節點的下一個節點。q向后移動直到找到第一個比p值大的節點,添加到數組中。
vector<int> nextLargerNodes(ListNode* head) {vector<int> result;ListNode* p=head;while(p!=nullptr){ListNode* q=p->next;int maxval=0;while(q!=nullptr){if(q->val > p->val){maxval=q->val;break;//找到第一個最大的就退出}q=q->next;}result.push_back(maxval);p=p->next;}return result;
}

解法2:單調棧。
右側更大可以使用單調棧。單調棧的關鍵是維持棧內元素的單調性。
棧中每個索引對應的 values 值從棧底到棧頂逐漸變小。在這里插入圖片描述

vector<int> nextLargerNodes(ListNode* head) {//將鏈表轉換為數組vector<int> values;ListNode* p=head;while(p!=nullptr){values.push_back(p->val);p=p->next;}//初始化結果數組int n=values.size();vector<int> result(n,0);//單調棧stack<int> st;for(int i=0;i<n;i++){//將要出棧的元素全部出完while(!st.empty() && values[i] > values[st.top()]){int idx=st.top();st.pop();result[idx]=values[i];}//棧空 || 當前值<棧頂值——入棧st.push(i);}return result;
}

1.3.2刪除右側有一個更大數值的節點

當前值與后面值比較:若存在一個值 > 當前值,將當前值刪掉。
思路與上述的單調棧差不多。重點在于棧內存儲的是節點,最后返回時候需要使用頭插法進行連接。

ListNode* removeNodes(ListNode* head) {stack<ListNode*> st;ListNode* p=head;while(p!=nullptr){//單調棧while(!st.empty() && p->val > st.top()->val){st.pop();}st.push(p);p=p->next;}//單調棧的元素“底大頂小”,因此實際需要從頭向下連接//重構鏈表ListNode* dummy=new ListNode();ListNode* q=dummy;while(!st.empty()){ListNode* node=st.top();st.pop();// 將當前節點插入到dummy和dummy->next之間node->next = dummy->next;dummy->next = node;}return dummy->next;
}

1.3.3交換K和倒數第K個節點

ListNode* swapNodes(ListNode* head, int k) {ListNode* dummy=new ListNode(0,head);//求鏈表的長度int length=0;ListNode* cur=head;while(cur!=nullptr){cur=cur->next;length++;}//找到第k個節點p,下標為k-1ListNode* p=dummy;for(int i=0;i<=k-1;i++){p=p->next;}//找到倒數第k個節點q,下標為length-kListNode* q=dummy;for(int i=0;i<=length-k;i++){q=q->next;}//交換swap(p->val,q->val);return head;
}

1.3.4合并0之間的節點

ListNode* mergeNodes(ListNode* head) {//新建一個鏈表ListNode* dummy=new ListNode(0);ListNode* cur=dummy;int sum=0;ListNode* p=head->next;while(p!=nullptr){if(p->val!=0){sum += p->val;}else{ListNode* newnode=new ListNode(sum);cur->next=newnode;cur=cur->next;sum=0;}p=p->next;}return dummy->next;;
}

1.4其他

序號題目鏈接
1鏈表組件https://leetcode.cn/problems/linked-list-components/description/?envType=problem-list-v2&envId=linked-list
2螺旋矩陣https://leetcode.cn/problems/spiral-matrix-iv/description/?envType=problem-list-v2&envId=linked-list
3臨界值間的距離https://leetcode.cn/problems/find-the-minimum-and-maximum-number-of-nodes-between-critical-points/description/?envType=problem-list-v2&envId=linked-list

1.4.1鏈表組件

在這里插入圖片描述

int numComponents(ListNode* head, vector<int>& nums) {// 將nums中的值存入哈希集合,便于快速查找unordered_set<int> numSet(nums.begin(), nums.end());int count=0;int flag=0;ListNode* p=head;while(p!=nullptr){//當前節點值在nums中if(numSet.count(p->val)){//之前沒碰到過:新的組件if(!flag){count++;flag=1;}}//當前節點值不在nums中else{ flag=0;}p=p->next;}return count;
}

1.4.2螺旋矩陣

給你兩個整數:m 和 n ,表示矩陣的維數。
另給你一個整數鏈表的頭節點 head 。
請你生成一個大小為 m x n 的螺旋矩陣,矩陣包含鏈表中的所有整數。鏈表中的整數從矩陣 左上角 開始、順時針 按 螺旋 順序填充。如果還存在剩余的空格,則用 -1 填充。

模擬螺旋填充的過程:

  • 螺旋填充的路徑是 “右→下→左→上” 的循環,每次完成一圈后縮小邊界。
    • 從左到右填充上邊界,完成后上邊界下移
    • 從上到下填充右邊界,完成后右邊界左移
    • 從右到左填充下邊界(如果還有空間),完成后下邊界上移
    • 從下到上填充左邊界(如果還有空間),完成后左邊界右移
  • 用四個變量控制當前填充的邊界:上邊界 (top)、下邊界 (bottom)、左邊界 (left)、右邊界 (right)
  • 從鏈表中依次取元素,按照螺旋路徑填充,直到所有元素用完或矩陣填滿
vector<vector<int>> spiralMatrix(int m, int n, ListNode* head) {// 初始化m×n矩陣,全部填充為-1vector<vector<int>> matrix(m, vector<int>(n, -1));//定義邊界int top=0;int bottom=m-1;int left=0;int right=n-1;//ListNode* current=head;while(current!=nullptr && top <= bottom && left <= right){// 1. 從左到右填充上邊界for (int col = left; col <= right && current != nullptr; col++) {matrix[top][col] = current->val;current = current->next;}top++; // 上邊界下移,該排已填滿// 2. 從上到下填充右邊界for (int row = top; row <= bottom && current != nullptr; row++) {matrix[row][right] = current->val;current = current->next;}right--; // 右邊界左移,該列已填滿// 3. 從右到左填充下邊界(需確保還有未填充的行)if (top <= bottom) {for (int col = right; col >= left && current != nullptr; col--) {matrix[bottom][col] = current->val;current = current->next;}bottom--; // 下邊界上移,該排已填滿}// 4. 從下到上填充左邊界(需確保還有未填充的列)if (left <= right) {for (int row = bottom; row >= top && current != nullptr; row--) {matrix[row][left] = current->val;current = current->next;}left++; // 左邊界右移,該列已填滿}}return matrix;
}

1.4.3臨界值的距離

模擬即可:

  • 使用三個指針prev、curr和next分別指向當前節點的前一個節點、當前節點和后一個節點。
  • 對于每個節點,檢查它是否是局部極大值點(大于前后節點)或局部極小值點(小于前后節點)。
  • 記錄所有臨界點的位置索引(從 1 開始計數)。
  • 計算出最小距離和最大距離。
vector<int> nodesBetweenCriticalPoints(ListNode* head) {if(head==nullptr || head->next==nullptr) return{-1,-1};vector<int> result;ListNode* pre=head;ListNode* cur=head->next;ListNode* next=cur->next;int pos=1;while(next!=nullptr){int ismax=(cur->val > pre->val) && (cur->val > next->val);int ismin=(cur->val < pre->val) && (cur->val < next->val);if(ismax || ismin) result.push_back(pos);//每一組極值pre=cur;cur=next;next=next->next;pos++;}if(result.size()<2) return {-1,-1};//計算最小距離(相鄰臨界點之間的最小距離)int mind=INT_MAX;for(int i=1;i<result.size();i++){mind=min(mind,result[i]-result[i-1]);}//最大距離(第一個和最后一個極值的距離)int maxd=result.back()-result.front();return {mind,maxd};
}

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

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

相關文章

【Android】OkHttp發起GET請求 POST請求

三三要成為安卓糕手 一&#xff1a;OkHttp介紹 OkHttp 是一個開源的、強大且高效的 HTTP 客戶端庫&#xff0c;主要用于在 Java后端和Android 項目中進行網絡請求。 //在gradle中添加依賴 com.squareup.okhttp3:okhttp:4.12.0二&#xff1a;GET請求/*** 使用OkHttp發起get請求*…

[Mysql數據庫] 知識點總結8

1. 請詳細描述在復制拓撲中參與復制的線程類型以及各自所承擔的功能。答&#xff1a;當從屬服務器連接到主服務器時&#xff0c;在主服務器上會創建 Binlog 轉儲線程&#xff0c;在從屬服務器上會默 認創建 I/O 線程和 SQL 線程。- Binlog 轉儲線程用于從二進制日志讀取事件并將…

250829-Gitlab數據備份與恢復

下面給你一份可落地的遷移方案&#xff0c;保證 GitLab 的數據和配置完整遷移到服務器 B。你當前用的是 GitLab Omnibus&#xff08;docker 版&#xff09;&#xff0c;數據都在你映射的 3 個目錄里&#xff08;/etc/gitlab, /var/log/gitlab, /var/opt/gitlab&#xff09;&…

吳恩達機器學習作業十一:異常檢測

數據集在作業一異常檢測異常檢測就是發現與大部分對象不同的對象&#xff0c;其實就是發現離群點。異常檢測有時也稱偏差檢測。異常對象是相對罕見的。用數據集建立概率模型p ( x )&#xff0c;如果新的測試數據在這個模型上小于某個閾值&#xff0c;則說它極大可能為異常點算法…

2000w 的數據量,mysql要進行幾次IO操作,為什么

在 MySQL 中&#xff0c;2000 萬數據量的表在進行查詢時所需的 ??IO 操作次數??主要取決于 ??索引結構&#xff08;B樹層級&#xff09;??、??查詢類型??和 ??數據分布特征??。以下是具體分析&#xff1a;一、B樹層級與 IO 次數的關系InnoDB 引擎通過 B樹索引管…

【代碼隨想錄day 22】 力扣 39. 組合總和

視頻講解&#xff1a;https://www.bilibili.com/video/BV1KT4y1M7HJ/?vd_sourcea935eaede74a204ec74fd041b917810c 文檔講解&#xff1a;https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html#%E6%80%9D%E8%B7%AF 力扣題目&#xff1a;https://leetcod…

DrissionPage 實戰:動態 IP 代理與百度翻譯 API 數據抓取

本文將詳細介紹如何使用 DrissionPage 實現動態 IP 代理訪問&#xff0c;并結合百度翻譯 API 進行數據抓取與處理。一、技術選型與架構設計1.1 為什么選擇 DrissionPage&#xff1f;DrissionPage 作為新一代網絡自動化工具&#xff0c;相比傳統 Selenium Requests 方案具有顯著…

策略模式:靈活應對算法動態切換

引言 在軟件開發中&#xff0c;我們常常會遇到需要在運行時動態選擇和切換算法或行為的場景。例如&#xff0c;電商系統中的多種支付方式、游戲中的不同難度設置&#xff0c;或是計算器中的各種運算符。傳統的方法可能會使用復雜的條件判斷語句&#xff08;如if-else或switch-c…

【C++ 】string類:深拷貝與淺拷貝解析

【C 】string類操作全解析-CSDN博客 1.stirng類的模擬實現 1.1 經典的string類問題 上面已經對string類進行了簡單的介紹&#xff0c;大家只要能夠正常使用即可。在面試中&#xff0c;面試官總喜歡要求自己來模擬實現string類&#xff0c;最主要是實現string類的構造、拷貝…

Decoder 解碼器

Decoder 解碼器&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h>#include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libswscale/swscale.h>#define WORD uint16_t #define DWORD ui…

globals() 小技巧

scheduler_class globals()[scheduler_class_name] Python 中一種 動態獲取類對象 的常用技巧&#xff0c;屬于 反射&#xff08;reflection&#xff09; 編程的范疇globals()Python 內置函數&#xff0c;返回一個 字典&#xff08;dict&#xff09;&#xff0c;包含當前模塊&…

Android Studio 9.png制作

一、新建 二、把要做的圖png導入進去 png圖片建議 根據內容預留1像素可拉伸區域 eg:純色或可漸變底色 三、右邊創建.9.png 四、雙擊打開 1、繪制黑邊 參考視頻 2、縮放到800% ,移至右下 3、在下面和右邊繪制整根黑線 4、根據png 位置左側和上側黑線 4.1 分析 紅色方框為…

【百度】C++開發(25屆提前批 一面)面經

文章目錄1. 代碼實現&#xff1a;說說LRU&#xff0c;并代碼實現LRU為什么使用哈希表&#xff1f;&#xff08;有兩個原因&#xff09;1. 僅用雙向鏈表的缺陷2. 引入哈希表的作用1. 快速查找&#xff1a;2. 快速插入與刪除&#xff1a;雙向鏈表 哈希表的協作過程舉例說明代碼實…

Word文檔怎么打印?Word打印技巧?【圖文詳解】單面/雙面/指定頁面/逆序等Word打印選項

一、問題背景 在日常辦公、學習場景中&#xff0c;Word文檔作為常用的文字處理載體&#xff0c;經常需要將電子內容轉化為紙質版本&#xff0c;比如提交報告、打印學習資料、整理文檔存檔等。 但不少用戶在嘗試打印Word文檔時&#xff0c;常會遇到各種阻礙&#xff1a;有的不清…

漫談《數字圖像處理》之基函數與基圖像

在數字圖像處理領域&#xff0c;基函數與基圖像是貫穿理論分析與實際應用的核心概念 —— 它們如同 “樂高積木”&#xff0c;將復雜的圖像信號拆解為可解釋、可操作的基本單元&#xff0c;支撐起壓縮、去噪、特征提取等一系列關鍵任務。從傳統的傅里葉變換到前沿的因子場理論&…

打開多個Excel文件后快速關閉所有的文檔,并且退出Excel應用

打開多個Excel文件后如果要快速關閉所有的文檔&#xff0c;并且退出Excel應用&#xff0c;可以按住Shift鍵右上角的號&#xff08;關閉按鈕&#xff09;。Word和PowerPoint也是一樣的操作。如果有文檔修改后沒有保存&#xff0c;會提示是否保存。作為補充&#xff0c;先來看看兩…

基于 PyTorch 構建 Dataset 與 DataLoader:從 TXT 文件讀取到新增類別全流程指南

基于 PyTorch 構建 Dataset 與 DataLoader&#xff1a;從 TXT 文件讀取到新增類別全流程指南在深度學習計算機視覺任務中&#xff0c;數據加載與預處理是模型訓練的基礎環節&#xff0c;直接影響模型的訓練效率與最終性能。PyTorch 作為主流深度學習框架&#xff0c;提供了Data…

hive on tez如果是2個大表union會寫幾次臨時文件到hdfs目錄,數據量如何計算

如果是2個大表union會寫幾次臨時文件到hdfs目錄&#xff0c;數據量如何計算 在Hive on Tez中&#xff0c;兩個大表執行UNION操作時&#xff0c;臨時文件的寫入次數和數據量&#xff0c;取決于UNION的類型&#xff08;UNION ALL還是UNION去重&#xff09;以及執行計劃的Stage劃分…

Web+js轉uni-app+ts

一、入手uni-app 官方文檔&#xff1a;uni-app官網 1.創建uni-app項目 1.1通過HBuilderX進行創建 官方地址&#xff1a;HBuilderX-高效極客技巧 1.2通過命令行創建 // js 版本的 npx degit dcloudio/uni-preset-vue#vite 項目名 npx degit dcloudio/uni-preset-vue#vite-…

IO_hw_8.29

1.使用fgets和fputs完成兩個文件的拷貝&#xff0c;要求文件名使用外部傳承2.注冊登錄代碼3.思維導圖4.牛客網刷題記錄