03、字节跳动-链表与树

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/

猜你喜欢

转载自blog.csdn.net/applehub/article/details/84936422