java連結串列面試題
本文包含連結串列的以下內容:
1、單鏈表的建立和遍歷
2、求單鏈表中節點的個數
3、查詢單鏈表中的倒數第k個結點(劍指offer,題15)
4、查詢單鏈表中的中間結點
5、合併兩個有序的單鏈表,合併之後的連結串列依然有序【出現頻率高】(劍指offer,題17)
6、單鏈表的反轉【出現頻率最高】(劍指offer,題16)
7、從尾到頭列印單鏈表(劍指offer,題5)
8、判斷單鏈表是否有環
9、取出有環連結串列中,環的長度
10、單鏈表中,取出環的起始點(劍指offer,題56)。本題需利用上面的第8題和第9題。
11、判斷兩個單鏈表相交的第一個交點(劍指offer,題37)
1、單鏈表的建立和遍歷:
- publicclass LinkList {
- public Node head;
- public Node current;
- //方法:向連結串列中新增資料
- publicvoid add(int data) {
- //判斷連結串列為空的時候
- if (head == null) {//如果頭結點為空,說明這個連結串列還沒有建立,那就把新的結點賦給頭結點
- head = new Node(data);
- current = head;
- } else {
- //建立新的結點,放在當前節點的後面(把新的結點合連結串列進行關聯)
- current.next = new Node(data);
- //把連結串列的當前索引向後移動一位
- current = current.next; //此步操作完成之後,current結點指向新新增的那個結點
- }
- }
- //方法:遍歷連結串列(列印輸出連結串列。方法的引數表示從節點node開始進行遍歷
- publicvoid print(Node node) {
- if (node == null) {
- return;
- }
- current = node;
- while (current != null) {
- System.out.println(current.data);
- current = current.next;
- }
- }
- class
- //注:此處的兩個成員變數許可權不能為private,因為private的許可權是僅對本類訪問。
- int data; //資料域
- Node next;//指標域
- public Node(int data) {
- this.data = data;
- }
- }
- publicstaticvoid main(String[] args) {
- LinkList list = new LinkList();
- //向LinkList中新增資料
- for (int i = 0; i < 10; i++) {
- list.add(i);
- }
- list.print(list.head);// 從head節點開始遍歷輸出
- }
- }
上方程式碼中,這裡面的Node節點採用的是內部類來表示(33行)。使用內部類的最大好處是可以和外部類進行私有操作的互相訪問。
注:內部類訪問的特點是:內部類可以直接訪問外部類的成員,包括私有;外部類要訪問內部類的成員,必須先建立物件。
為了方便新增和遍歷的操作,在LinkList類中新增一個成員變數current,用來表示當前節點的索引(03行)。
這裡面的遍歷連結串列的方法(20行)中,引數node表示從node節點開始遍歷,不一定要從head節點遍歷。
2、求單鏈表中節點的個數:
注意檢查連結串列是否為空。時間複雜度為O(n)。這個比較簡單。
核心程式碼:
- //方法:獲取單鏈表的長度
- publicint getLength(Node head) {
- if (head == null) {
- return0;
- }
- int length = 0;
- Node current = head;
- while (current != null) {
- length++;
- current = current.next;
- }
- return length;
- }
3、查詢單鏈表中的倒數第k個結點:
3.1 普通思路:
先將整個連結串列從頭到尾遍歷一次,計算出連結串列的長度size,得到連結串列的長度之後,就好辦了,直接輸出第(size-k)個節點就可以了(注意連結串列為空,k為0,k為1,k大於連結串列中節點個數時的情況
)。時間複雜度為O(n),大概思路如下:
- publicint findLastNode(int index) { //index代表的是倒數第index的那個結點
- //第一次遍歷,得到連結串列的長度size
- if (head == null) {
- return -1;
- }
- current = head;
- while (current != null) {
- size++;
- current = current.next;
- }
- //第二次遍歷,輸出倒數第index個結點的資料
- current = head;
- for (int i = 0; i < size - index; i++) {
- current = current.next;
- }
- return current.data;
- }
如果面試官不允許你遍歷連結串列的長度,該怎麼做呢?接下來就是。
3.2 改進思路:(這種思路在其他題目中也有應用)
這裡需要宣告兩個指標:即兩個結點型的變數first和second,首先讓first和second都指向第一個結點,然後讓second結點往後挪k-1個位置,此時first和second就間隔了k-1個位置,然後整體向後移動這兩個節點,直到second節點走到最後一個結點的時候,此時first節點所指向的位置就是倒數第k個節點的位置。時間複雜度為O(n)
程式碼實現:(初版)
- public Node findLastNode(Node head, int index) {
- if (node == null) {
- returnnull;
- }
- Node first = head;
- Node second = head;
- //讓second結點往後挪index個位置
- for (int i = 0; i < index; i++) {
- second = second.next;
- }
- //讓first和second結點整體向後移動,直到second結點為Null
- while (second != null) {
- first = first.next;
- second = second.next;
- }
- //當second結點為空的時候,此時first指向的結點就是我們要找的結點
- return first;
- }
程式碼實現:(最終版)(考慮k大於連結串列中結點個數時的情況時,丟擲異常)
上面的程式碼中,看似已經實現了功能,其實還不夠健壯:
要注意k等於0的情況;
如果k大於連結串列中節點個數時,就會報空指標異常,所以這裡需要做一下判斷。
核心程式碼如下:
- public Node findLastNode(Node head, int k) {
- if (k == 0 || head == null) {
- returnnull;
- }
- Node first = head;
- Node second = head;
- //讓second結點往後挪k-1個位置
- for (int i = 0; i < k - 1; i++) {
- System.out.println("i的值是" + i);
- second = second.next;
- if (second == null) { //說明k的值已經大於連結串列的長度了
- //throw new NullPointerException("連結串列的長度小於" + k); //我們自己丟擲異常,給使用者以提示
- returnnull;
- }
- }
- //讓first和second結點整體向後移動,直到second走到最後一個結點
- while (second.next != null) {
- first = first.next;
- second = second.next;
- }
- //當second結點走到最後一個節點的時候,此時first指向的結點就是我們要找的結點
- return first;
- }
4、查詢單鏈表中的中間結點:
同樣,面試官不允許你算出連結串列的長度,該怎麼做呢?
思路:
和上面的第2節一樣,也是設定兩個指標first和second,只不過這裡是,兩個指標同時向前走,second指標每次走兩步,first指標每次走一步,直到second指標走到最後一個結點時,此時first指標所指的結點就是中間結點。注意連結串列為空,連結串列結點個數為1和2的情況。時間複雜度為O(n)。
程式碼實現:
- //方法:查詢連結串列的中間結點
- public Node findMidNode(Node head) {
- if (head == null) {
- returnnull;
- }
- Node first = head;
- Node second = head;
- //每次移動時,讓second結點移動兩位,first結點移動一位
- while (second != null && second.next != null) {
- first = first.next;
- second = second.next.next;
- }
- //直到second結點移動到null時,此時first指標指向的位置就是中間結點的位置
- return first;
- }
上方程式碼中,當n為偶數時,得到的中間結點是第n/2 + 1個結點。比如連結串列有6個節點時,得到的是第4個節點。
5、合併兩個有序的單鏈表,合併之後的連結串列依然有序:
這道題經常被各公司考察。
例如:
連結串列1:
1->2->3->4
連結串列2:
2->3->4->5
合併後:
1->2->2->3->3->4->4->5
解題思路:
挨著比較連結串列1和連結串列2。
這個類似於歸併排序。尤其要注意兩個連結串列都為空、和其中一個為空的情況。只需要O (1) 的空間。時間複雜度為O (max(len1,len2))
程式碼實現:
- //兩個引數代表的是兩個連結串列的頭結點
- public Node mergeLinkList(Node head1, Node head2) {
- if (head1 == null && head2 == null) { //如果兩個連結串列都為空
- returnnull;
- }
- if (head1 == null) {
- return head2;
- }
- if (head2 == null) {
- return head1;
- }
- Node head; //新連結串列的頭結點
- Node current; //current結點指向新連結串列
- // 一開始,我們讓current結點指向head1和head2中較小的資料,得到head結點
- if (head1.data < head2.data) {
- head = head1;
- current = head1;
- head1 = head1.next;
- } else {
- head = head2;
- current = head2;
- head2 = head2.next;
- }
- while (head1 != null && head2 != null) {
- if (head1.data < head2.data) {
- current.next = head1; //新連結串列中,current指標的下一個結點對應較小的那個資料
- current = current.next; //current指標下移
- head1 = head1.next;
- } else {
- current.next = head2;
- current = current.next;
- head2 = head2.next;
- }
- }
- //合併剩餘的元素
- if (head1 != null) { //說明連結串列2遍歷完了,是空的
- current.next = head1;
- }
- if (head2 != null) { //說明連結串列1遍歷完了,是空的
- current.next = head2;
- }
- return head;
- }
程式碼測試:
- publicstaticvoid main(String[] args) {
- LinkList list1 = new LinkList();
- LinkList list2 = new LinkList();
- //向LinkList中新增資料
- for (int i = 0; i < 4; i++) {
- list1.add(i);
- }
- for (int i = 3; i < 8; i++) {
- list2.add(i);
- }
- LinkList list3 = new LinkList();
- list3.head = list3.mergeLinkList(list1.head, list2.head); //將list1和list2合併,存放到list3中
- list3.print(list3.head);// 從head節點開始遍歷輸出
- }
上方程式碼中用到的add方法和print方法和第1小節中是一致的。
執行效果:
注:《劍指offer》中是用遞迴解決的,感覺有點難理解。
6、單鏈表的反轉:【出現頻率最高】
例如連結串列:
1->2->3->4
反轉之後:
4->2->2->1
思路:
從頭到尾遍歷原連結串列,每遍歷一個結點,將其摘下放在新連結串列的最前端。注意連結串列為空和只有一個結點的情況。時間複雜度為O(n)
方法1:(遍歷)
- //方法:連結串列的反轉
- public Node reverseList(Node head) {
- //如果連結串列為空或者只有一個節點,無需反轉,直接返回原連結串列的頭結點
- if (head == null || head.next == null) {
- return head;
- }
- Node current = head;
- Node next = null; //定義當前結點的下一個結點
- Node reverseHead = null; //反轉後新連結串列的表頭
- while (current != null) {
- next = current.next; //暫時儲存住當前結點的下一個結點,因為下一次要用
- current.next = reverseHead; //將current的下一個結點指向新連結串列的頭結點
- reverseHead = current;
- current = next; // 操作結束後,current節點後移
- }
- return reverseHead;
- }
上方程式碼中,核心程式碼是第16、17行。
方法2:(遞迴)
這個方法有點難,先不講了。
7、從尾到頭列印單鏈表:
對於這種顛倒順序的問題,我們應該就會想到棧,後進先出。所以,這一題要麼自己使用棧,要麼讓系統使用棧,也就是遞迴。注意連結串列為空的情況。時間複雜度為O(n)
注:不要想著先將單鏈表反轉,然後遍歷輸出,這樣會破壞連結串列的結構,不建議。
方法1:(自己新建一個棧)
- //方法:從尾到頭列印單鏈表
- publicvoid reversePrint(Node head) {
- if (head == null) {
- return;
- }
- Stack<Node> stack = new Stack<Node>(); //新建一個棧
- Node current = head;
- //將連結串列的所有結點壓棧
- while (current != null) {-
- stack.push(current); //將當前結點壓棧
- current = current.next;
- }
- //將棧中的結點列印輸出即可
- while (stack.size() > 0) {
- System.out.println(stack.pop().data); //出棧操作
- }
- }
方法2:(使用系統的棧:遞迴,程式碼優雅簡潔)
- publicvoid reversePrint(Node head) {
- if (head == null) {
- return;
- }
- reversePrint(head.next);
- System.out.println(head.data);
- }
總結:方法2是基於遞迴實現的,戴安看起來簡潔優雅,但有個問題:當連結串列很長的時候,就會導致方法呼叫的層級很深,有可能造成棧溢位。而方法1的顯式用棧,是基於迴圈實現的,程式碼的魯棒性要更好一些。
8、判斷單鏈表是否有環:
這裡也是用到兩個指標,如果一個連結串列有環,那麼用一個指標去遍歷,是永遠走不到頭的。
因此,我們用兩個指標去遍歷:first指標每次走一步,second指標每次走兩步,如果first指標和second指標相遇,說明有環。時間複雜度為O (n)。
方法:
- //方法:判斷單鏈表是否有環
- publicboolean hasCycle(Node head) {
- if (head == null) {
- returnfalse;
- }
- Node first = head;
- Node second = head;
- while (second != null) {
- first = first.next; //first指標走一步
- second = second.next.next; second指標走兩步
- if (first == second) { //一旦兩個指標相遇,說明連結串列是有環的
- returntrue;
- }
- }
- returnfalse;
- }
完整版程式碼:(包含測試部分)
這裡,我們還需要加一個過載的add(Node node)方法,在建立單向迴圈連結串列時要用到。
- LinkList.java:
- publicclass LinkList {
- public Node head;
- public Node current;
- //方法:向連結串列中新增資料
- publicvoid add(int data) {
- //判斷連結串列為空的時候
- if (head == null) {//如果頭結點為空,說明這個連結串列還沒有建立,那就把新的結點賦給頭結點
- head = new Node(data);
- current = head;
- } else {
- //建立新的結點,放在當前節點的後面(把新的結點合連結串列進行關聯)
- current.next = new Node(data);
- //把連結串列的當前索引向後移動一位
- current = current.next;
- }
- }
- //方法過載:向連結串列中新增結點
- publicvoid add(Node node) {
- if (node == null) {
- return;
- }
- if (head == null) {
- head = node;
- current = head;
- } else {
- current.next = node;
- current = current.next;
- }
- }
- //方法:遍歷連結串列(列印輸出連結串列。方法的引數表示從節點node開始進行遍歷
- publicvoid print(Node node) {
- if (node == null) {
- return;
- }
- current = node;
- while (current != null) {
- System.out.println(current.data);
- current = current.next;
- }
- }
- //方法:檢測單鏈表是否有環
- publicboolean hasCycle(Node head) {
- if (head == null) {
- returnfalse;
- }
- Node first = head;
- Node second = head;
- while (second != null) {
- first = first.next; //first指標走一步
- second = second.next.next; //second指標走兩步
- if (first == second) { //一旦兩個指標相遇,說明連結串列是有環的
- returntrue;
- }
- }
- returnfalse;
- }
- class Node {
- //注:此處的兩個成員變數許可權不能為private,因為private的許可權是僅對本類訪問。
- int data; //資料域
- Node next;//指標域
- public Node(int data) {
- this.data = data;
- }
- }
- publicstaticvoid main(String[] args) {
- LinkList list = new LinkList();
- //向LinkList中新增資料
- for (int i = 0; i < 4; i++) {
- list.add(i);
- }
- list.add(list.head); //將頭結點新增到連結串列當中,於是,單鏈表就有環了。備註:此時得到的這個環的結構,是下面的第8小節中圖1的那種結構。
- System.out.println(list.hasCycle(list.head));
- }
- }
檢測單鏈表是否有環的程式碼是第50行。
88行:我們將頭結點繼續往連結串列中新增,此時單鏈表就環了。最終執行效果為true。
如果刪掉了88行程式碼,此時單鏈表沒有環,執行效果為false。
9、取出有環連結串列中,環的長度:
我們平時碰到的有環連結串列是下面的這種:(圖1)
上圖中環的長度是4。
但有可能也是下面的這種:(圖2)
此時,上圖中環的長度就是3了。
那怎麼求出環的長度呢?
思路:
這裡面,我們需要先利用上面的第7小節中的hasCycle方法(判斷連結串列是否有環的那個方法),這個方法的返回值是boolean型,但是現在要把這個方法稍做修改,讓其返回值為相遇的那個結點。然後,我們拿到這個相遇的結點就好辦了,這個結點肯定是在環裡嘛,我們可以讓這個結點對應的指標一直往下走,直到它回到原點,就可以算出環的長度了。
方法:
- //方法:判斷單鏈表是否有環。返回的結點是相遇的那個結點
- public Node hasCycle(Node head) {
- if (head == null) {
- returnnull;
- }
- Node first = head;
- Node second = head;
- while (second != null) {
- first = first.next;
- second = second.next.next;
- if (first == second) { //一旦兩個指標相遇,說明連結串列是有環的
- return first; //將相遇的那個結點進行返回
- }
- }
- returnnull;
- }
- //方法:有環連結串列中,獲取環的長度。引數node代表的是相遇的那個結點
- publicint getCycleLength(Node node) {
- if (head == null) {
- return0;
- }
- Node current = node;
- int length = 0;
- while (current != null) {
- current = current.next;
- length++;
- if (current == node) { //當current結點走到原點的時候
- return length;
- }
- }
- return length;
- }
完整版程式碼:(包含測試部分)
- publicclass LinkList {
- public Node head;
- public Node current;
- publicint size;
- //方法:向連結串列中新增資料
- publicvoid add(int data) {
- //判斷連結串列為空的時候
- if (head == null) {//如果頭結點為空,說明這個連結串列還沒有建立,那就把新的結點賦給頭結點
- head = new Node(data);
- current = head;
- } else {
- //建立新的結點,放在當前節點的後面(把新的結點合連結串列進行關聯)
- current.next = new Node(data);
- //把連結串列的當前索引向後移動一位
- current = current.next; //此步操作完成之後,current結點指向新新增的那個結點
- }
- }
- //方法過載:向連結串列中新增結點
- publicvoid add(Node node) {
- if (node == null) {
- return;
- }
- if (head == null) {
- head = node;
- current = head;
- } else {
- current.next = node;
- current = current.next;
- }
- }
- //方法:遍歷連結串列(列印輸出連結串列。方法的引數表示從節點node開始進行遍歷
- publicvoid print(Node node) {
- if (node == null) {
- return;
- }
- current = node;
- while (current != null) {
- System.out.println(current.data);
- current = current.next;
- }
- }
- //方法:判斷單鏈表是否有環。返回的結點是相遇的那個結點
- public Node hasCycle(Node head) {
- if (head == null) {
- returnnull;
- }
- Node first = head;
- Node second = head;
- while (second != null) {
- first = first.next;
- second = second.next.next;
- if (first == second) { //一旦兩個指標相遇,說明連結串列是有環的
- return first; //將相遇的那個結點進行返回
- }
- }
- returnnull;
- }
- //方法:有環連結串列中,獲取環的長度。引數node代表的是相遇的那個結點
- publicint getCycleLength(Node node) {
- if (head == null) {
- return0;
- }
- Node current = node;
- int length = 0;
- while (current != null) {
- current = current.next;
- length++;
- if (current == node) { //當current結點走到原點的時候
- return length;
- }
- }
- return length;
- }
- class Node {
- //注:此處的兩個成員變數許可權不能為private,因為private的許可權是僅對本類訪問。
- int data; //資料域
- Node next;//指標域
- public Node(int data) {
- this.data = data;
- }
- }
- publicstaticvoid main(String[] args) {
- LinkList list1 = new LinkList();
- Node second = null; //把第二個結點記下來
- //向LinkList中新增資料
- for (int i = 0; i < 4; i++) {
- list1.add(i);
- if (i == 1) {
- second = list1.current; //把第二個結點記下來
- }
- }
- list1.add(second); //將尾結點指向連結串列的第二個結點,於是單鏈表就有環了,備註:此時得到的環的結構,是本節中圖2的那種結構
- Node current = list1.hasCycle(list1.head); //獲取相遇的那個結點
- System.out.println("環的長度為" + list1.getCycleLength(current));
- }
- }
執行效果:
如果將上面的104至122行的測試程式碼改成下面這樣的:(即:將圖2中的結構改成圖1中的結構)
- publicstaticvoid main(String[] args) {
- LinkList list1 = new LinkList();
- //向LinkList中新增資料
- for (int i = 0; i < 4; i++) {
- list1.add(i);
- }
- list1.add(list1.head); //將頭結點新增到連結串列當中(將尾結點指向頭結點),於是,單鏈表就有環了。備註:此時得到的這個環的結構,是本節中圖1的那種結構。
- Node current = list1.hasCycle(list1.head);
- System.out.println("環的長度為" + list1.getCycleLength(current));
- }
執行結果:
如果把上面的程式碼中的第8行刪掉,那麼這個連結串列就沒有環了,於是執行的結果為0。
10、單鏈表中,取出環的起始點:
我們平時碰到的有環連結串列是下面的這種:(圖1)
上圖中環的起始點1。
但有可能也是下面的這種:(圖2)
此時,上圖中環的起始點是2。
方法1:
這裡我們需要利用到上面第8小節的取出環的長度的方法getCycleLength,用這個方法來獲取環的長度length。拿到環的長度length之後,需要用到兩個指標變數first和second,先讓second指標走length步;然後讓first指標和second指標同時各走一步,當兩個指標相遇時,相遇時的結點就是環的起始點。
注:為了找到環的起始點,我們需要先獲取環的長度,而為了獲取環的長度,我們需要先判斷是否有環。所以這裡面其實是用到了三個方法。
程式碼實現:
方法1的核心程式碼:
- //方法:獲取環的起始點。引數length表示環的長度
- public Node getCycleStart(Node head, int cycleLength) {
- if (head == null) {
- returnnull;
- }
- Node first = head;
- Node second = head;
- //先讓second指標走length步
- for (int i = 0; i < cycleLength; i++) {
- second = second.next;
- }
- //然後讓first指標和second指標同時各走一步
- while (first != null && second != null) {
- first = first.next;
- second = second.next;
- if (first == second) { //如果兩個指標相遇了,說明這個結點就是環的起始點
- return first;
- }
- }
- returnnull;
- }
完整版程式碼:(含測試部分)
- publicclass LinkList {
- public Node head;
- public Node current;
- publicint size;
- //方法:向連結串列中新增資料
- publicvoid add(int data) {
- //判斷連結串列為空的時候
- if (head == null) {//如果頭結點為空,說明這個連結串列還沒有建立,那就把新的結點賦給頭結點
- head = new Node(data);
- current = head;
- } else {
- //建立新的結點,放在當前節點的後面(把新的結點合連結串列進行關聯)
- current.next = new Node(data);
- //把連結串列的當前索引向後移動一位
- current = current.next; //此步操作完成之後,current結點指向新新增的那個結點
- }
- }
- //方法過載:向連結串列中新增結點
- publicvoid add(Node node) {
- if (node == null) {
- return;
- }
- if (head == null) {
- head = node;
- current = head;
- } else {
- current.next = node;
- current = current.next;
- }
- }
- //方法:遍歷連結串列(列印輸出連結串列。方法的引數表示從節點node開始進行遍歷
- publicvoid print(Node node) {
- if (node == null) {
- return;
- }
- current = node;
- while (current != null) {
- System.out.println(current.data);
- current = current.next;
- }
- }
- //方法:判斷單鏈表是否有環。返回的結點是相遇的那個結點
- public Node hasCycle(Node head) {
- if (head == null) {
- returnnull;
- }
- Node first = head;
- Node second = head;
- while (second !=
相關推薦
java連結串列面試題
本文包含連結串列的以下內容: 1、單鏈表的建立和遍歷 2、求單鏈表中節點的個數 3、查詢單鏈表中的倒數第k個結點(劍指offer,題15) 4、查詢單鏈表中的中間結點 5、合併兩個有序的單鏈表,合併之後的連結串列依然有序【出現頻率高】(劍指offer,題17) 6
連結串列面試題程式碼總結(java)
這是原文連結:http://www.jianshu.com/p/a64d1ef95980 最近總結了一下資料結構和演算法的題目,這是第二篇文章,關於連結串列的,第一篇文章關於二叉樹的參見 廢話少說,上鍊表的資料結構 class ListNode { ListNode ne
連結串列面試題集合
連結串列面試題: 1. 比較順序表和連結串列的優缺點,說說它們分別在什麼場景下使用? 順序表一般用於查詢,可隨機訪問; 連結串列一般用於增刪改,不可隨機訪問; 如果資料元素不多,兩種方式沒有太大的差別 如果資料元素不定,建議使用連結串列 順序表
連結串列面試題C++
注意頭結點的處理,如果倒敘記得將新的尾節點指向空。 示例一 給定一個整數num,如何在節點值有序的連結串列中插入一個節點值為num的節點,並且保證這個單鏈表依然有序。 #include<iostream> #include<thread> using
單鏈表的基本操作及連結串列面試題
單鏈表的基本操作及連結串列面試題 程式程式碼如下: LinkList.h #ifndef __LINKLIST_H__ #define __LINKLIST_H__ #include <stdio.h> #include <stdlib.
連結串列面試題----約瑟夫環相關
約瑟夫環相關連結串列面試題 繼上篇部落格之------------ 什麼是約瑟夫環 約瑟夫環 判斷是否成環 求環的長度 環的入口點
一文搞定連結串列面試題系列之二 —— Leetcode234. Palindrome Linked List迴文連結串列\
連結串列薈萃二: 迴文連結串列 列表解法 迴文連結串列 題目:迴文連結串列給定一個連結串列,判斷該連結串列是否是迴文連結串列,要求O(n)時間複雜度,O(1)空間複雜度。 Given a singly linked
連結串列面試題
關於連結串列已經學了有一段時間了,今天抽空進行了整理,列出來常見的有關連結串列的面試題,以下想法如有瑕疵望批評指出,希望能給初學者帶來一點參考和價值 從尾到頭列印單鏈表 遞迴列印 // 1、從尾到頭列印單鏈表 遞迴 void ListReversePrint(ListN
【連結串列面試題】【進階】
1、查詢倒數第 k 個連結串列 題目描述:給定一個單向連結串列 List ,要你設計演算法找出倒數第 K 個結點並列印 struct ListNode { DataType m_Value; ListNode* m_pNext; }; ListNode* FindKt
【資料結構】連結串列面試題升級版
1、複雜連結串列的複製 複雜連結串列 一個連結串列的每個結點,有一個next指標指向下一個結點,還有一個random指標指向這個連結串列中的隨機一個結點或者NULL。 現在要求複製這個連結串列,並返回複製後的新連結串列。 思路如下: 複雜連結串列的資料型別: typedef str
【資料結構】連結串列面試題
1、倒序列印連結串列 (1)非遞迴方式 程式碼如下: void ReversePrint(ListNode **pFirst) { ListNode *last = NULL; ListNode *cur = NULL; assert(*pFirst != NULL); w
連結串列面試題:返回倒數第k個節點
題目來源:劍指offer 方法一: 首先我們先得出連結串列一共有多少個節點標記為count個,然後正數第count-k+1個就是倒數第k個節點,迴圈得到就可以。 程式碼: class Solution { public: ListNode*
【連結串列面試題】合併兩個有序連結串列, 合併後依然有序
程式碼 // 合併兩個有序連結串列 SListNode * MergeOrderedList(SListNode *p1First, SListNode *p2First) { SListNode*
連結串列面試題之合併兩個有序連結串列
關於合併兩個有序的連結串列,假定該連結串列為升序排列,排列後的新表依舊升序。以下提供兩種方法進行排列。 建立新節點為空,依次後續插入法 Node* MergeTwoList1(N
連結串列面試題小結(待完成)
以下程式碼使用的公共結構: 連結串列節點: struct ListNode { int data; ListNode *next; }; 輔助函式: //make a list ListNode *makeList(int *arr, int n) { if(a
連結串列面試題 ---- 複雜連結串列的複製
一個連結串列的每個結點,有一個next指標指向下一個結點,還有一個random指標指向這個連結串列中的一個隨機結點或者NULL,題目要求實現複製這個連結串列,返回複製後的新連結串列 如圖所示: 1.先將單鏈表複製,如下圖 2.找複雜指標,對新節點複
連結串列面試題總結 C/C++
資料結構和演算法,是我們程式設計最重要的兩大元素,可以說,我們的程式設計,都是在選擇和設計合適的資料結構來存放資料,然後再用合適的演算法來處理這些資料。 在面試中,最經常被提及的就是連結串列,因為它簡單,但又因為需要對指標進行操作,凡是涉及到指標的,都需要我
關於連結串列面試題的一些理解
面試題一.刪除無頭單鏈表的非尾結點 Del_Nottail(pLinkNode pos); 顧名思義刪除非尾結點就是刪除的結點不是最後一個結點,之前在實現連結串列功能的時
連結串列面試題之快慢指標問題(一) 查詢連結串列中間節點
查詢連結串列中間節點 一.問題描述 給點一個連結串列,返回該連結串列的中間節點。 二.問題分析 假定一個連結串列中節點資料依次為(單數):1->2->3-&
螞蟻金服初級Java電話面試 面試題
ringbuf str eem 螞蟻 ren 電話 什麽 死鎖 hashmap 1.String, StringBuffer, StringBuilder 的區別,為什麽String 不可改變,StringBuilder可以改變? 2.HashMap 是不是有序的,有哪些有