前端手撕題總結篇(算法篇——來自Leetcode牛客)

鏈表

在這里插入圖片描述

指定區域反轉

找到區間(頭和為 for循環當**時)->反轉鏈表(返回反轉過后的頭和尾)->連接

function reverseBetween( head ,  m ,  n ) {//preEnd&cur&nextStart  cur.next斷開if(m===n)return head;const vHeadNode=new ListNode(0);vHeadNode.next=head;let preEnd=null;let cur = vHeadNode;for(let i=0;i<n;i++){if(i===m-1)preEnd=cur;cur=cur.next;}let nextStart =cur.next;cur.next=null;const [start,end]=reverseList(preEnd.next);preEnd.next=start;end.next=nextStart;return vHeadNode.next;
}
function reverseList(head){const vHeadNode=new ListNode(-1);vHeadNode.next=head;let cur=head;while(cur){const next=cur.next;cur.next=vHeadNode.next;vHeadNode.next=cur;cur=next;}return [vHeadNode.next,head];
}

每K個一組反轉(★★★)

指針preEnd&cur->while(cur)->curStart=cur;curEnd=preEnd,if(!preEnd)return vHead.next->反轉連接-》cur=nextStart&preEnd=End(翻轉過后)

function reverseKGroup(head, k) {// write code hereconst vHeadNode=new ListNode(-1);vHeadNode.next=head;let preEnd=vHeadNode;let cur=head;while(cur){let curStart=cur;let curEnd=preEnd;for(let i=0;i<k;i++){curEnd=curEnd.next;if(!curEnd)return vHeadNode.next;}let nextStart=curEnd.next;curEnd.next=null;const [start,end]=reverseSubList(curStart);preEnd.next=start;end.next=nextStart;cur=nextStart;preEnd=end;}return vHeadNode.next;
}
//反思一下自己吧!!!簡單但請仔細
function reverseSubList(head) {let dummyNode = new ListNode(0);let cur = head;while (cur) {let next = cur.next;cur.next = dummyNode.next;dummyNode.next = cur;cur = next;}return [dummyNode.next, head];
}

合并K個已排序鏈表(★★★)

基礎:合并兩個已排序鏈表->歸并排序

export function mergeKLists(lists: ListNode[]): ListNode {// // write code here// //nlogn --->歸并// //拆開// //返回的是ListNode不是數組類型,ts編譯會報錯!太好了// if(lists.length<=1) return lists[0];// const mid=Math.floor(lists.length/2);// const left=mergeKLists(lists.slice(0,mid));// const right=mergeKLists(lists.slice(mid));// return merge(left,right);if(lists.length<=1)return lists[0];const mid =Math.floor(lists.length/2);const left = mergeKLists(lists.slice(0,mid));const right=mergeKLists(lists.slice(mid));return merge(left,right);
}function merge(pHead1:ListNode, pHead2:ListNode) {const dummyNode = new ListNode(0);let cur = dummyNode;while (pHead1 && pHead2) {if (pHead1.val < pHead2.val) {cur.next = pHead1;pHead1 = pHead1.next;} else {cur.next = pHead2;pHead2 = pHead2.next;}cur = cur.next;}cur.next=pHead1?pHead1:pHead2;return dummyNode.next;
}

基礎

//雙指針判斷是否有環
function hasCycle( head ) {if(!head)return false;//起點相同let fast=head;let slow=head;//&&這里出錯while(fast&&slow&&fast.next){//先跳后判斷fast=fast.next.next;slow=slow.next;if(fast===slow)return true;}return false;}
//鏈表環的入口
function EntryNodeOfLoop(pHead)
{if(!pHead||!pHead.next)return null;let fast=pHead;let slow=pHead;while(fast&&slow&&fast.next){fast=fast.next.next;slow=slow.next;if(fast===slow){fast=pHead;//這!!!while(fast!==slow){fast=fast.next;slow=slow.next;}return fast;}}
}
//倒數第	K個節點
function FindKthToTail( pHead ,  k ) {// write code here//測試案例II,求長度!const genLen=(curNode)=>{let count=0;while(curNode){curNode=curNode.next;count++;}return count;}const len=genLen(pHead);//判斷是否合理!!!if(k>len)return null;let fast=pHead,slow=pHead;while(k--){fast=fast.next;}//這條件!!!while(fast){fast=fast.next;slow=slow.next;}return slow;
}
//刪除鏈表的倒數第n個節點(虛擬頭結點)
function removeNthFromEnd( head ,  n ) {// write code herelet vHeadNode=new ListNode(0);vHeadNode.next=head;let fast=vHeadNode;let slow=vHeadNode;while(n--){fast=fast.next;}// //若不借助虛擬節點// //這一步真是太關鍵了// if(quick == null){//     return head.next// }//key:此處判斷條件就不一樣 fast.next&&slow.next!!!while(fast.next){fast=fast.next;slow=slow.next;}slow.next=slow.next.next;return vHeadNode.next;
}
//兩鏈表第一個公共節點
export function FindFirstCommonNode(pHead1: ListNode, pHead2: ListNode): ListNode {//另一種思路:求長度差+先走+while相等退出返回//循環條件應該是當兩個指針沒有相遇時繼續循環,即while(cur1 !== cur2)。//這樣,當它們相等時(無論是相交節點還是都為null)就退出循環并返回cur1(此時等于cur2)if(!pHead1||!pHead2)return null;let cur1=pHead1;let cur2=pHead2;while(cur1!==cur2){cur1=cur1?cur1.next:pHead2;cur2=cur2?cur2.next:pHead1;}return cur2;
}

鏈表相加(★★★)

先反轉+鏈表相加(大數相加)+反轉結果

function addInList( head1 ,  head2 ) {// write code hereconst dummyNode=new ListNode(0);let cur=dummyNode;let reversedList1=reverseList(head1);let reversedList2=reverseList(head2);let carry=0;while(reversedList1||reversedList2||carry){let val1=reversedList1?reversedList1.val:0;let val2=reversedList2?reversedList2.val:0;const sum=val1+val2+carry;const digit=sum%10;const node =new ListNode(digit);carry=Math.floor(sum/10);cur.next=node;cur=cur.next;//!!!移動指針!!!鏈表相加肯定要移動指針!!!if(reversedList1)reversedList1=reversedList1.next;if(reversedList2)reversedList2=reversedList2.next;}return reverseList(dummyNode.next);
}
function reverseList(head){let vHeadNode=new ListNode(0);let cur=head;while(cur){let next=cur.next;cur.next=vHeadNode.next;vHeadNode.next=cur;cur=next;}return vHeadNode.next;
}

單鏈表排序

分治(歸并)排序
key:找鏈表中點(需借助虛擬頭結點)->返回條件->合并(兩個已排序鏈表)

function sortInList( head ) {// write code here//分治if(!head||!head.next)return head;const middle=findMiddle(head);let right=middle.next;middle.next=null;const leftHead=sortInList(head);const rightHead=sortInList(right);const merge=(leftHead,rightHead)=>{const dummyNode=new ListNode(0);let cur=dummyNode;let head1=leftHead;let head2=rightHead;while(head1&&head2){if(head1.val>head2.val){cur.next=head2;head2=head2.next;}else{cur.next=head1;head1=head1.next;}cur=cur.next;}cur.next=head1?head1:head2;return dummyNode.next;}return merge(leftHead,rightHead);
}
function findMiddle(head){//要虛擬頭結點!!!!這一個函數錯了,導致整個通過不了!!!const dummyNode=new ListNode(0);dummyNode.next=head;let fast=dummyNode;let slow=dummyNode;while(fast&&fast.next){fast=fast.next.next;slow=slow.next;}return slow;
}

回文鏈表

找鏈表中節點(同上)-》反轉左側鏈表-》比較,若有不對等返回false

export function isPail(head: ListNode): boolean {// write code hereconst middle=findMiddle(head);let leftHead=head;let rightHead=middle.next;middle.next=null;const reverseList=(head:ListNode|null):ListNode=>{const dummyNode=new ListNode(0);let cur=head;while(cur){const next=cur.next;cur.next=dummyNode.next;dummyNode.next=cur;cur=next;}return dummyNode.next;}let reverseRightHead=reverseList(rightHead);while(leftHead&&reverseRightHead){if(leftHead.val!==reverseRightHead.val)return false;leftHead=leftHead.next;reverseRightHead=reverseRightHead.next;}return true;}
function findMiddle(head:ListNode):ListNode{const dummyNode=new ListNode(0);dummyNode.next=head;let fast=dummyNode;let slow=dummyNode;while(fast&&fast.next){fast=fast.next.next;slow=slow.next;}return slow;
}

鏈表奇偶排序

指針:odd、even&evenHead
條件:even&&even.head
返回:head

function oddEvenList( head ) {if(!head||!head.next)return head;// write code herelet odd=head;//奇數let even=head.next;//偶數let evenHead=even;//記錄偶節點的頭結點//終止條件:偶節點&偶節點.next不為空!!!!//even&&even.nextwhile(even&&even.next){odd.next=even.next;odd=odd.next;even.next=odd.next;even=even.next;}odd.next=evenHead;return head;
}

刪除重復元素

I->cur=head

function deleteDuplicates( head ) {// write code herelet cur=head;//鏈表靠著時next指針,不要想著還計算長度什么!while(cur){while(cur.next&&cur.val===cur.next.val){cur.next=cur.next.next;}cur=cur.next;}return head;}

II(?)

  1. 虛擬頭結點
  2. 找到if(cur.next.val=cur.next.next.val)并存儲至temp,內部while(cur.next&&cur.next.val=temp)刪除節點
  3. 否則就是cur=cur.next
export function deleteDuplicates(head: ListNode): ListNode {// // write code here// const vHeadNode=new ListNode(0);// vHeadNode.next=head;// let cur=vHeadNode;// let temp=0;// while(cur.next&&cur.next.next){//     if(cur.next.val===cur.next.next.val){//         temp=cur.next.val;//         //相同的節點都跳過//         while(cur.next&&cur.next.val===temp){//             cur.next=cur.next.next;//         }//     }else{//         //其他節點就向后移//         cur=cur.next;//     }// }// return vHeadNode.next;const vHeadNode=new ListNode(0);vHeadNode.next=head;//虛擬頭結點,解決第一個和第二個元素就相同的情況let cur=vHeadNode;let temp=0;while(cur.next&&cur.next.next){if(cur.next.val===cur.next.next.val){temp=cur.next.val;while(cur.next&&cur.next.val===temp){cur.next=cur.next.next;}}else{cur=cur.next;}}return vHeadNode.next;
}

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

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

相關文章

從Excel到工時管理系統:企業如何選擇更高效的工時記錄工具?

還在為手工統計員工工時而頭疼嗎&#xff1f;月末堆積如山的Excel表格、反復核對的數據、層出不窮的差錯&#xff0c;這些問題正在拖慢企業的發展步伐。8Manage工時管理系統發現&#xff0c;傳統手工記錄不僅耗費大量人力&#xff0c;更讓寶貴的工時數據難以轉化為有效的管理決…

Java設計模式之《命令模式》

目錄 1、介紹 1.1、命令模式定義 1.2、對比 1.3、典型應用場景 2、命令模式的結構 2.1、組成部分&#xff1a; 2.2、整體流程 3、實現 3.1、沒有命令模式 3.2、命令模式寫法 4、命令模式的優缺點 前言 java設計模式分類&#xff1a; 1、介紹 1.1、命令模式定義 命…

【動態規劃算法】路徑問題

什么是動態規劃算法動態規劃&#xff08;Dynamic Programming&#xff0c;簡稱 DP&#xff09;是一種通過分解復雜問題為重疊子問題&#xff0c;并存儲子問題的解以避免重復計算&#xff0c;從而高效求解具有特定性質&#xff08;重疊子問題、最優子結構&#xff09;問題的算法…

Java基本技術講解

一、基礎語法三要素 暫時無法在飛書文檔外展示此內容 &#x1f511; 黃金法則?&#xff1a;每個變量都要聲明類型&#xff01;二、程序邏輯控制&#xff08;游戲行為核心&#xff09; 條件判斷&#xff1a;if-else - “岔路口選擇” // 撿到金幣邏輯 if (isTouching(Coin.clas…

【網絡基礎2】路由器的 “兩扇門”:二層接口和三層接口到底有啥不一樣?

目錄 前言:路由器不是只有 “插網線的口” 一、先搞懂一個基礎:路由器是 “網絡交通樞紐” 二、二層接口:“小區內部的單元門”,只認 “住戶身份證” 1. 啥是二層接口? 2. 用 “小區內部串門” 理解二層接口 步驟 1:手機打包數據,寫上 “收件人身份證” 步驟 2:二…

MLIR TableGen

簡介 TableGen 是一種領域特定語言&#xff08;DSL&#xff09;&#xff0c;TableGen 的設計目標是允許編寫靈活的描述&#xff0c;并將記錄的通用特性提取出來&#xff0c;從而減少重復代碼并提高代碼的可維護性。 TableGen的工作流程&#xff1a; 前端解析&#xff1a; Ta…

2、docker容器命令 | 信息查看

1、命令總覽命令作用docker ps查看運行中的容器&#xff08;-a查看所有容器&#xff09;docker logs [CONTAINER]查看容器日志&#xff08;-f實時追蹤日志&#xff09;docker inspect [CONTAINER]查看容器詳細信息&#xff08;JSON格式&#xff09;docker stats [CONTAINER]實時…

【MySQL】MySQL中鎖有哪些?

一、按照粒度分類&#xff1a; 粒度越小&#xff0c;并發度越高&#xff0c;鎖開銷越大。 1.全局鎖&#xff1a; 作用&#xff1a; 鎖定整個MySQL實例(所有數據庫)。適用場景&#xff1a; 全庫邏輯部分。(確保備份期間數據的一致性。)實現方式&#xff1a; 通過 FLUSH TABLES W…

語義分割--deeplabV3+

根據論文網絡結構圖講一下&#xff1a;網絡分為兩部分&#xff1a;encoder和decoder部分。 Encoder&#xff1a;DCNN就是主干網絡&#xff0c;例如resnet&#xff0c;Xception&#xff0c;MobileNet這些&#xff08;主干網絡也要使用空洞卷積&#xff09;&#xff0c;對dcnn的結…

Azure DevOps 中的代理

必知詞匯 深入研究 Azure DevOps 中的代理之前需要掌握的基本概念: 代理:Azure DevOps 中的代理是一個軟件組件,負責執行流水線中的任務和作業。這可能包括數據中心內的物理服務器、本地或云端托管的虛擬機,甚至是容器化環境。這些代理可以在各種操作系統和環境中運行,例如…

AUTOSAR進階圖解==>AUTOSAR_SRS_ADCDriver

AUTOSAR ADC驅動詳解 基于AUTOSAR標準的ADC驅動模塊需求規范分析目錄 ADC驅動模塊概述 關鍵概念定義 ADC驅動架構 ADC驅動在AUTOSAR分層架構中的位置ADC驅動的主要職責 ADC驅動配置結構 通用配置(AdcGeneral)硬件單元配置(AdcHwUnit)通道配置(AdcChannel)通道組配置(AdcChanne…

寶馬集團與SAP聯合打造生產物流數字化新標桿

在德國雷根斯堡的寶馬工廠&#xff0c;每57秒就有一輛新車下線。這座工廠不僅是汽車制造的基地&#xff0c;更是寶馬集團向SAP S/4HANA云平臺轉型的先鋒項目。通過“RISE with SAP”計劃&#xff0c;寶馬將該工廠的運營系統全面遷移至SAP S/4HANA Cloud Private Edition&#x…

Go 語言實戰:構建一個高性能的 MySQL + Redis 應用

引言&#xff1a;為什么是 Go MySQL Redis&#xff1f;在現代后端技術棧中&#xff0c;Go MySQL Redis 的組合堪稱“黃金搭檔”&#xff0c;被廣泛應用于各種高并發業務場景。Go 語言&#xff1a;以其卓越的并發性能、簡潔的語法和高效的執行效率&#xff0c;成為構建高性能…

Excel超級處理器,多個word表格模板中內容提取到Excel表格中

在職場中&#xff0c;很多人習慣在word里插入表格&#xff0c;設計模板&#xff0c;填寫內容&#xff0c;一旦有多個word文件需要整理在excel表格中&#xff0c;最常見的工作方式就是每個word文件打開&#xff0c;復制&#xff0c;粘貼到excel表格里&#xff0c;這樣的工作方式…

前端工程化:ES6特性

本文為個人學習筆記整理&#xff0c;僅供交流參考&#xff0c;非專業教學資料&#xff0c;內容請自行甄別 文章目錄一、let與var1.1、越獄問題1.2、變量的重復聲明1.3、變量提升問題二、解構2.1、數組解構2.2、對象解構2.3、方法解構三、鏈判斷四、參數默認值五、箭頭函數六、模…

大屏項目展示

一、項目克隆與基礎操作 我們參考的項目 互聯網設備可視化平臺---IofTV-Screen: ??一個基于 vue、datav、Echart 框架的物聯網可視化(大屏展示)模板,提供數據動態刷新渲染、屏幕適應、數據滾動配置,內部圖表自由替換、Mixins注入等功能,持續更新.... 將次項目克隆到本…

基于R語言地理加權回歸、主成份分析、判別分析等空間異質性數據分析實踐技術應用

在自然和社會科學領域有大量與地理或空間有關的數據&#xff0c;這一類數據一般具有嚴重的空間異質性&#xff0c;而通常的統計學方法并不能處理空間異質性&#xff0c;因而對此類型的數據無能為力。以地理加權回歸為基礎的一系列方法&#xff1a;經典地理加權回歸&#xff0c;…

【Flask 基礎 ①】 | 路由、參數與模板渲染

0 序言 Flask 是 Python 生態中一款輕量級 Web 框架&#xff0c;以簡潔、靈活著稱。 學習 Flask 的意義在于&#xff1a; 快速開發&#xff1a;通過少量代碼即可搭建功能完整的 Web 應用&#xff1b;理解原理&#xff1a;其設計清晰體現了 Web 框架的核心邏輯&#xff0c;如路由…

wordpress登陸前登陸后顯示不同的頂部菜單

在WordPress中讓“未登錄”和“已登錄”用戶看到不同的頂部菜單&#xff0c;最干凈、最安全、最可維護的做法是&#xff1a; 在同一個菜單位置(themelocation)里&#xff0c;根據is_user_logged_in()動態切換菜單。 下面給出三種常見實現方式&#xff0c;按推薦程度排序。任選…

【昇騰推理PaddleOCR】生產級部署方式

已知的在昇騰上推理Paddle OCR有三種方法&#xff1a; 概要&#xff1a; PyTorch官方提供了昇騰插件包&#xff0c;安裝后雖然可以支持PytorchOCR和PaddlePaddle的推理任務&#xff0c;但性能較低。換句話說&#xff0c;PaddlePaddle框架層面支持了昇騰&#xff0c;但具體到某個…