鏈表知識回顧

類型:單鏈表,雙鏈表、循環鏈表

存儲:在內存中不是連續存儲

刪除操作:即讓c的指針指向e即可,無需釋放d,因為java中又內存回收機制

添加節點:?

鏈表的構造函數

public class ListNode {// 結點的值int val;// 下一個結點ListNode next;// 節點的構造函數(無參)public ListNode() {}// 節點的構造函數(有一個參數)public ListNode(int val) {this.val = val;}// 節點的構造函數(有兩個參數)public ListNode(int val, ListNode next) {this.val = val;this.next = next;}
}

可以直接用java自帶的LinkedList類實現鏈表的初始化

import java.util.LinkedList;public class Main {public static void main(String[] args) {// 創建一個空的鏈表LinkedList<Integer> list = new LinkedList<>();// 向鏈表中添加元素list.add(1);list.add(2);list.add(3);// 打印鏈表內容System.out.println(list);}
}

鏈表的聲明:

Java標準庫提供了LinkedList類,位于java.util包中。它的特點如下:

  • 實現細節LinkedList底層通常實現為雙向鏈表,這意味著每個節點除了指向下一個節點,還保存對前一個節點的引用。
  • 接口實現:除了實現List接口外,LinkedList還實現了Deque接口,使其既可以當作列表使用,也可以當作隊列(或雙端隊列)使用。
  • 增刪操作add(), remove(), offer(), poll()等方法在鏈表頭尾插入或刪除元素時性能較高。
  • 遍歷操作:由于鏈表沒有下標索引,隨機訪問通常較慢。如果頻繁使用隨機訪問,可以考慮使用ArrayList,ArrayList 底層是基于動態數組實現的
LinkedList<Integer> list = new LinkedList<Integer>();
List<Integer> list1 =new LinkedList<Integer>();
List<Integer> list2 =new ArrayList<>();
LinkedList list3 = new LinkedList();

?上述是常見的鏈表的聲明方式

第一種,變量的聲明類型和實際實現類型都是LinkedList,可直接調用 LinkedList 類中特有的方法,并且聲明了泛型Integer,確保只能存儲 Integer 類型的數據,編譯期間就能進行類型檢查,避免了類型轉換異常。

第二種,聲明類型是接口 List類型,實際實現的類型確實LinkedList,但只能調用 List 接口中定義的方法。如果需要使用 LinkedList 特有的方法(如隊列或雙端隊列相關的方法),則需要顯式地進行類型轉換。同樣使用了泛型 <Integer>,確保類型安全。

第三種聲明類型是接口List,實現的是ArrayList類型,ArrayList 支持快速隨機訪問,時間復雜度為 O(1)。在數組中間插入或刪除元素時需要移動元素,時間復雜度為 O(n);而 LinkedList 在任意位置添加或刪除(假如已經有相應節點引用)通常更高效。

第四種實現的是原始類型(因為沒有使用泛型),編譯器不會對集合中的數據進行類型檢查,

手搓鏈表

public class Linked {static class Node{int data;Node next;public Node(){};public Node(int data){this.data = data;this.next =null;}}public static class SingleLinkedList{private Node head;public void addFirst(int data){Node newNode = new Node(data);newNode.next = head;head = newNode;}public void addLast(int data){Node newNode = new Node(data);if(head ==null){head = newNode;return;}Node curr = head;while(curr.next != null){curr = curr.next;}curr.next = newNode;}public boolean remove(int data){if(head == null){//若鏈表為空,則刪除失敗return false;}if(head.data == data){//還要先判斷頭節點是否時要刪除的head = head.next;return true;}Node curr = head;while(curr.next != null && curr.next.data != data){curr = curr.next;}if (curr.next != null) {curr.next = curr.next.next;return true;}return false;}public void printList() {Node curr = head;while (curr != null) {System.out.print(curr.data + " ");curr = curr.next;}System.out.println("null");}}public static void main(String[] args) {SingleLinkedList list = new SingleLinkedList();list.addFirst(4);list.addFirst(3);list.addFirst(2);list.addFirst(1);list.addLast(5);list.addLast(6);list.printList();//1 2 3 4 5 6 nulllist.remove(6);list.printList();//1 2 3 4 5 null}
}

反轉鏈表

題意:反轉一個單鏈表。

示例: 輸入: 1->2->3->4->5->NULL 輸出: 5->4->3->2->1->NULL,即右移

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseList(ListNode head) {// 如果鏈表為空,則直接返回nullif(head == null){return null;}// prev指針初始化為null,最后會成為反轉后鏈表的頭節點ListNode prev = null;// cur指針指向當前要處理的節點,開始時指向鏈表頭headListNode cur = head;// temp用于保存當前節點cur的下一個節點,防止在改變指針關系后丟失引用ListNode temp = null;// 當當前節點不為空時,循環執行反轉操作while (cur != null) {// 保存cur的下一個節點,防止鏈表斷裂temp = cur.next; // 此時temp指向cur的下一節點// 將當前節點的next指針指向前一個節點,實現局部反轉cur.next = prev; // 當前節點的next由原來的下一個節點變為前一個節點// 將prev移動到當前節點位置,為下一次反轉操作做準備prev = cur;// 將cur后移到下一個節點,也就是之前保存的tempcur = temp;}// 循環結束后,prev指向反轉后的鏈表頭節點,返回它作為新的鏈表起點return prev;}
}

鏈表內兩兩交換

給定一個鏈表,兩兩交換其中相鄰的節點,并返回交換后的鏈表。

你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。

解1:

  • 創建一個虛擬頭節點dummy指向head,定義current指針真相虛擬頭節點
  • 進入循環體內,確定current每次后面都能有兩個節點進行交換操作
  • 定義first和second分別指向第一個節點和第二個節點,
  • 然后讓第二個節點指向第一個節點,第一個節點指向下一個要交換的第一個節點,最后讓current指向交換后的第一個節點
  • 2,3,4循環操作,直至不夠節點互換退出循環,返回虛擬頭節點之后的head
public class Solution {public ListNode swapPairs(ListNode head) {// 創建啞結點,它的 next 指向原鏈表的頭ListNode dummy = new ListNode(0);dummy.next = head;ListNode current = dummy;// 循環條件:當前結點后面至少有兩個節點while (current.next != null && current.next.next != null) {// 定義要交換的兩個節點ListNode first = current.next;ListNode second = current.next.next;// 交換節點:// 1. 先將 first 指向 second 的下一個節點first.next = second.next;// 2. second 指向 firstsecond.next = first;// 3. current 指向 second,完成與前面的連接current.next = second;// 移動 current,跳過剛才交換的兩個節點current = first;}// 返回啞結點的 next,即新的頭節點return dummy.next;}
}

解2:將鏈表轉換為隊列處理,在重建鏈表

import java.util.ArrayList;
import java.util.List;public class Solution {public ListNode swapPairs(ListNode head) {if (head == null || head.next == null) {return head;}// 1. 將鏈表節點存入數組List<ListNode> nodes = new ArrayList<>();ListNode current = head;while (current != null) {nodes.add(current);current = current.next;}// 2. 在數組中交換相鄰節點for (int i = 0; i < nodes.size() - 1; i += 2) {// 交換nodes[i]與nodes[i+1]ListNode temp = nodes.get(i);nodes.set(i, nodes.get(i+1));nodes.set(i+1, temp);}// 3. 重建鏈表(根據交換后的數組重設每個節點的next指針)for (int i = 0; i < nodes.size() - 1; i++) {nodes.get(i).next = nodes.get(i + 1);}// 最后一個節點的next設為nullnodes.get(nodes.size() - 1).next = null;// 4. 返回新的鏈表頭(數組中第一個元素)return nodes.get(0);}
}

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

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

相關文章

詳解與FTP服務器相關操作

目錄 什么是FTP服務器 搭建FTP服務器相關 ?編輯 Unity中與FTP相關的類 上傳文件到FTP服務器 使用FTP服務器上傳文件的關鍵點 開始上傳 從FTP服務器下載文件到客戶端 使用FTP下載文件的關鍵點 開始下載 關于FTP服務器的其他操作 將文件的上傳&#xff0c;下載&…

Day92 | 靈神 | 二叉樹 路徑總和

Day92 | 靈神 | 二叉樹 路徑總和 112.路徑總和 112. 路徑總和 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 1.遞歸函數意義 如果在根節點為t的樹中可以找到長度為target的路徑就返回true&#xff0c;找不到就返回false 2.參數和返回值 bool tra(TreeNode …

探索鴻蒙應用開發:ArkTS應用執行入口揭秘

# 探索鴻蒙應用開發&#xff1a;ArkTS應用執行入口揭秘 在鴻蒙應用開發的領域中&#xff0c;ArkTS作為聲明式開發語言&#xff0c;為開發者們帶來了便捷與高效。對于剛接觸鴻蒙開發的小伙伴來說&#xff0c;搞清楚ArkTS應用程序的執行入口是邁向成功開發的關鍵一步。今天&…

【Web API系列】Web Shared Storage API之WorkletSharedStorage深度解析與實踐指南

前言 在現代Web開發領域&#xff0c;數據存儲與隱私保護的矛盾始終存在。傳統存儲方案如LocalStorage和Cookies面臨著日益嚴格的安全限制&#xff0c;而跨域數據共享的需求卻在持續增長。正是在這樣的背景下&#xff0c;Web Shared Storage API應運而生&#xff0c;其核心組件…

探索鴻蒙沉浸式:打造無界交互體驗

一、鴻蒙沉浸式簡介 在鴻蒙系統中&#xff0c;沉浸式是一種極具特色的設計理念&#xff0c;它致力于讓用戶在使用應用時能夠全身心投入到內容本身&#xff0c;而盡可能減少被系統界面元素的干擾。通常來說&#xff0c;就是將應用的內容區巧妙地延伸到狀態欄和導航欄所在的界面…

機器學習03——K近鄰

K近鄰算法學習筆記 一、算法簡介 K近鄰算法&#xff08;K - Nearest Neighbors&#xff0c;簡稱KNN&#xff09;是一種簡單而有效的分類和回歸算法。它的核心思想是“近朱者赤&#xff0c;近墨者黑”&#xff0c;即一個數據點的類別或值可以通過其周圍最近的K個鄰居來判斷。K…

序列化 反序列化實例

在Python中&#xff0c; pickle 模塊常用于實現對象的序列化和反序列化&#xff0c;以下是一個簡單的實例&#xff1a; import pickle # 定義一個類 class Person: def __init__(self, name, age): self.name name self.age age # 創建一個Person對象 person Person("…

代碼隨想錄算法訓練營第十九天

LeetCode題目: 77. 組合216. 組合總和 III17. 電話號碼的字母組合2537. 統計好子數組的數目(每日一題)516. 最長回文子序列1039. 多邊形三角剖分的最低得分543. 二叉樹的直徑124. 二叉樹中的最大路徑和2246. 相鄰字符不同的最長路徑 其他: 今日總結 往期打卡 77. 組合 跳轉: 7…

存算分離看場景

計算機行業是唯一一個比時裝行業概念更多的行業。概念頻出&#xff0c;最慢的話半年一定出一個&#xff0c;短的話半個月就能看到新的名詞和技術甚至是概念。 存算分離的概念 我第一次聽到存算分離時候還是從Hadoop上聽到的。然后就去問什么是存算分離。聽了講解以后&#xf…

MCP協議,.Net 使用示例

服務器端示例 基礎服務器 以下是一個基礎的 MCP 服務器示例&#xff0c;它使用標準輸入輸出&#xff08;stdio&#xff09;作為傳輸方式&#xff0c;并實現了一個簡單的回顯工具&#xff1a; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.H…

智能語音處理+1.5使用PocketSphinxshinx實現語音轉文本(100%教會)

歡迎來到智能語音處理系列的最后一篇文章&#xff0c;到這里,基本上語音處理是沒問題了. 第一篇:智能語音處理1.1下載需要的庫(100%實現)-CSDN博客 第二篇:智能語音識別1.2用SAPI實現文本轉語音(100%教會)-CSDN博客 第三篇:智能語音處理1.3用SpeechLib實現文本轉語音(100%教會)…

Kubernetes 節點摘除指南

目錄 一、安全摘除節點的標準流程 1. 確認節點名稱及狀態 2. 標記節點為不可調度 3. 排空&#xff08;Drain&#xff09;節點 4. 刪除節點 二、驗證節點是否成功摘除 1. 檢查節點列表 2. 檢查節點詳細信息 3. 驗證 Pod 狀態 三、徹底清理節點&#xff08;可選&#xf…

信息安全管理與評估2021年國賽正式卷答案截圖以及十套國賽卷

2021年全國職業院校技能大賽高職組 “信息安全管理與評估”賽項 任務書1 賽項時間 共計X小時。 賽項信息 賽項內容 競賽階段 任務階段 競賽任務 競賽時間 分值 第一階段 平臺搭建與安全設備配置防護 任務1 網絡平臺搭建 任務2 網絡安全設備配置與防護 第二…

3D語義地圖中的全局路徑規劃!iPPD:基于3D語義地圖的指令引導路徑規劃視覺語言導航

作者&#xff1a; Zehao Wang, Mingxiao Li, Minye Wu, Marie-Francine Moens, Tinne Tuytelaars 單位&#xff1a;魯汶大學電氣工程系&#xff0c;魯汶大學計算機科學系 論文標題&#xff1a; Instruction-guided path planning with 3D semantic maps for vision-language …

《AI大模型應知應會100篇》第20篇:大模型倫理準則與監管趨勢

第20篇&#xff1a;大模型倫理準則與監管趨勢 摘要 隨著人工智能&#xff08;AI&#xff09;技術的飛速發展&#xff0c;尤其是大模型&#xff08;如GPT、PaLM等&#xff09;在自然語言處理、圖像生成等領域的廣泛應用&#xff0c;AI倫理問題和監管挑戰日益凸顯。本文將梳理當…

【Ai】dify:Linux環境安裝 dify 詳細步驟

一、什么是dify Dify 是一個 開源的大語言模型(LLM)應用開發平臺,旨在幫助開發者快速構建基于 AI 的應用程序,例如智能對話助手、知識庫問答、內容生成工具等。它提供了可視化的流程編排、模型集成、數據管理等功能,降低了開發門檻,支持快速迭代和部署。 核心功能與特點…

CentOS 操作系統下搭建 tsung性能測試環境

寫在前面 為何這么安裝,實際就是這么做的,這是經過好幾次實踐得出的經驗總結。 這為了讓大家更清楚的知道怎么安裝 tsung性能測試環境,按步照搬的安裝即可。 步驟 1、 下載軟件安裝包 CentOS-6.0-x86_64-bin-DVD1.iso jdk-6u4-linux-x64-rpm.bin erlang: otp_src_1…

Vulkanised

Vulkanised 1. About VulkanisedReferences The Premier Vulkan Developer Conference premier /?premi?(r)/ n. 總理&#xff1b;(尤用于報章等) 首相&#xff1b;(加拿大的) 省總理&#xff1b;地區總理 adj. 第一的&#xff1b;首要的&#xff1b;最著名的&#xff1b;最…

C++之 動態數組

一、新建一個動態數組 數組名和下標操作符[]的組合可以被替換成一個指向該數組的基地址的指針和對應的指針運算&#xff1a; int a[20]; int *x a; 指針變量 x 指向數組 a 的地址&#xff0c; a[0] 和 *x 都代表數組的第一個元素。 于是&#xff0c;根據指針運算原則&…

ubuntu1804服務器開啟ftp,局域網共享特定文件給匿名用戶

要在 Ubuntu 18.04 上設置一個 FTP 服務器&#xff0c;滿足以下要求&#xff1a; 允許匿名登錄&#xff08;無需賬號密碼&#xff09;。指定分享特定目錄下的文件。只允許只讀下載。 可以使用 vsftpd&#xff08;Very Secure FTP Daemon&#xff09;來實現。以下是詳細步驟&a…