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/