03、位元組跳動-連結串列與樹
阿新 • • 發佈:2018-12-10
1、合併兩個有序連結串列
public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode listNode = new ListNode(0); ListNode firstNode = listNode; while (l1 != null && l2 != null) { if (l1.val <= l2.val) { listNode.next = l1; l1 = l1.next; } else { listNode.next = l2; l2 = l2.next; } listNode = listNode.next; } while (l1 != null) { listNode.next = l1; l1 = l1.next; listNode = listNode.next; } while (l2 != null) { listNode.next = l2; l2 = l2.next; listNode = listNode.next; } return firstNode.next; }
原文:https://blog.csdn.net/hocsoul/article/details/80048940
2、反轉連結串列
public ListNode reverseList3(ListNode pHead){ if(pHead==null || pHead.next == null){ //如果沒有結點或者只有一個結點直接返回pHead return pHead; } ListNode pNext = pHead.next; //儲存當前結點的下一結點 pHead.next = null; //打斷當前結點的指標域 ListNode reverseHead = reverseList3(pNext); //遞迴結束時reverseHead一定是新連結串列的頭結點 pNext.next = pHead; //修改指標域 return reverseHead; }
原文:https://blog.csdn.net/u013132035/article/details/80589657
3、兩數相加
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null) { return l2; } if (l2 == null) { return l1; } ListNode p1 = l1; ListNode p2 = l2; ListNode root = new ListNode(0); // 頭結點 ListNode r = root; root.next = l1; int carry = 0; // 初始進位 int sum; while (p1 != null && p2 != null) { sum = p1.val + p2.val + carry; p1.val = sum % 10; // 本位的結果 carry = sum / 10; // 本次進位 r.next = p1; r = p1; // 指向最後一個相加的結點 p1 = p1.next; p2 = p2.next; } if (p1 == null) { r.next = p2; } else { r.next = p1; } // 最後一次相加還有進位 if (carry == 1) { // 開始時r.next是第一個要相加的結點 while (r.next != null) { sum = r.next.val + carry; r.next.val = sum % 10; carry = sum / 10; r = r.next; } // 都加完了還有進位,就要建立一個新的結點 if (carry == 1) { r.next = new ListNode(1); } } return root.next; } }
原文:https://blog.csdn.net/DERRANTCM/article/details/46905467
4、排序連結串列
package com.main;
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
public class Main {
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
//平分結點,分成兩個分支
ListNode cur = null, slow = head, fast = head;
while (fast != null && fast.next != null) {//如果是奇數個結點,多出來的一個結點放在了後面的部分
cur = slow;
slow = slow.next;
fast = fast.next.next;
}
cur.next = null;
//每個分支都要排序,然後按序合併
ListNode l1 = sortList(head);
ListNode l2 = sortList(slow);
//按序合併,子分支和大分支都在這裡合併
return merge(l1, l2);
}//sortList
public ListNode merge(ListNode l1, ListNode l2) {
ListNode res = new ListNode(0), p = res;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
res.val = l1.val;
p.next = l1;//這一句別忘了
l1 = l1.next;
} else {
res.val = l2.val;
p.next = l2;
l2 = l2.next;
}
p = p.next;
}//while
if (l1 != null) {
p.next = l1;
}
if (l2 != null) {
// p.next = l2.next;不能是p.next = l2.next
p.next = l2;
}
return res.next;// ListNode res = new ListNode(0)因為第一個結點是0,所以這裡是 res.next,而不是res
}//merge
public static void main(String[] args) {
ListNode A = new ListNode(6);
A.next = new ListNode(2);
A.next.next = new ListNode(4);
A.next.next.next = new ListNode(3);
A.next.next.next.next = new ListNode(5);
Main main = new Main();
ListNode C = main.sortList(A);
System.out.println(C);
}
}
原文:https://blog.csdn.net/u010002184/article/details/76793696
5、環形連結串列 II
public ListNode detectCycle( ListNode head ) {
if( head == null || head.next == null ){
return null;
}
ListNode fp = head, sp = head;
while( fp != null && fp.next != null){
sp = sp.next;
fp = fp.next.next;
//判斷是否成環
if( fp == sp ){
break;
}
}
if( fp == null || fp.next == null ){
return null;
}
//fp到環入口距離 = head到環入口距離
sp = head;
while( fp != sp ){
sp = sp.next;
fp = fp.next;
}
return sp;
}
連結:https://www.jianshu.com/p/a352d46e7c41
6、相交連結串列
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null)
return null;
int headALength = 0;
int headBLength = 0;
ListNode p = headA;
while (headA != null){
++ headALength;
headA = headA.next;
}
p = headB;
while (headB != null){
++ headBLength;
headB = headB.next;
}
while (headALength > headBLength) {
headA = headA.next;
headALength --;
}
while (headBLength > headALength) {
headB = headB.next;
headBLength --;
}
while (headA != null) {
if (headA == headB)
return headA;
headA = headA.next;
headB = headB.next;
}
return null;
}
原文:https://blog.csdn.net/hocsoul/article/details/80151330
7、合併K個排序連結串列
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0)
return null;
// PriorityQueue 是堆,預設小頂堆
PriorityQueue<ListNode> min = new PriorityQueue<ListNode>(11, new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
return o1.val - o2.val;
}
});
// 加入所有連結串列的第一個結點,非空
for (ListNode node : lists)
if (node != null)
min.offer(node);
ListNode head = new ListNode(0);
ListNode cur = head;
while (!min.isEmpty()) {
ListNode temp = min.poll();
cur.next = temp;
cur = cur.next;
// 邊取邊加入
if (temp.next != null)
min.offer(temp.next);
}
// 注意斷鏈
cur.next = null;
return head.next;
}
原文:https://blog.csdn.net/mine_song/article/details/69501383
8、二叉樹的最近公共祖先
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 左右子樹探索時發現目標節點,則通過返回值標記
if(root == null || p == root || q == root) {
return root;
}
// 檢視左子樹中是否有目標結點,沒有為null
TreeNode l = lowestCommonAncestor(root.left,p,q);
// 檢視右子樹中是否有目標結點,沒有為null
TreeNode r = lowestCommonAncestor(root.right,p,q);
//都不為空,說明做右子樹都有目標結點,則公共祖先就是本身
if(l!= null && r!= null) {
return root;
}
// 其他情況,則要繼續向上標記,顯示此節點下邊有目標節點
return l != null?l:r;
}
}
原文:https://blog.csdn.net/github_34514750/article/details/52229129
9、二叉樹的鋸齒形層次遍歷
public class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if (root == null) {
return result;
}
Stack<TreeNode> currLevel = new Stack<TreeNode>();
Stack<TreeNode> nextLevel = new Stack<TreeNode>();
Stack<TreeNode> tmp;
currLevel.push(root);
boolean normalOrder = true;
while (!currLevel.isEmpty()) {
ArrayList<Integer> currLevelResult = new ArrayList<Integer>();
while (!currLevel.isEmpty()) {
TreeNode node = currLevel.pop();
currLevelResult.add(node.val);
if (normalOrder) {
if (node.left != null) {
nextLevel.push(node.left);
}
if (node.right != null) {
nextLevel.push(node.right);
}
} else {
if (node.right != null) {
nextLevel.push(node.right);
}
if (node.left != null) {
nextLevel.push(node.left);
}
}
}
result.add(currLevelResult);
tmp = currLevel;
currLevel = nextLevel;
nextLevel = tmp;
normalOrder = !normalOrder;
}
return result;
}
}
參考:https://www.jiuzhang.com/solutions/binary-tree-zigzag-level-order-traversal/