LeetCode经典编程题(三)

1. binary-tree-preorder-traversal

Description

Given a binary tree, return the preorder traversal of its nodes’ values.

For example:
Given binary tree{1,#,2,3},

   1
    \
     2
    /
   3

return[1,2,3].

Note: Recursive solution is trivial, could you do it iteratively?

Solution
idea
  1. recursive solution - node.val, getPreOrder(node.left), getPreOrder(node.right)
  2. iterative solution - Use a stack, if the root != null push it into the stack. When the stack isn’t empty, we pop one node and add it into the result list, then push its right child and left child into the stack. (FILO, push right first, then push left.)
Code

recursive solution

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.*;
public class Solution {
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> preOrder = new ArrayList<Integer>();
        getPreOrder(preOrder, root);
        return preOrder;
    }
    private void getPreOrder(ArrayList<Integer> preOrder, TreeNode node){
        if(node == null){
            return;
        }else{
            preOrder.add(node.val);
            getPreOrder(preOrder, node.left);
            getPreOrder(preOrder, node.right);
        }
    }
}

iterative solution

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.*;
public class Solution {
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> preOrder = new ArrayList<Integer>();
        if(root == null){
            return preOrder;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            if(node != null){
                preOrder.add(node.val);
                stack.push(node.right);
                stack.push(node.left);
            }
        }
        return preOrder;
    }
    
}

2. reorder-list

Description

Given a singly linked list L: L 0→L 1→…→L n-1→L n,
reorder it to: L 0→L n →L 1→L n-1→L 2→L n-2→…

You must do this in-place without altering the nodes’ values.

For example,
Given{1,2,3,4}, reorder it to{1,4,2,3}.

Solution
idea
  1. Use fast and slow pointer to find the middle of the list
  2. Reverse right part.
  3. Merge left and right part.
Code

do this in-place

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
import java.util.*;
public class Solution {
    public void reorderList(ListNode head) {
        if(head == null || head.next == null || head.next.next == null){
            return;
        }
        // slow -> half of the list
        ListNode fast = head, slow = head;
        while(fast.next!=null&&fast.next.next!=null){
            fast = fast.next.next;
            slow = slow.next;
        }
        
        ListNode rightPart = slow.next;
        slow.next = null;
        // reverse right Part
        ListNode pre = null;
        while(rightPart != null){
            ListNode next = rightPart.next;
            rightPart.next = pre;
            pre = rightPart;
            rightPart = next;
        }
        // merge
        ListNode left = head;
        while(pre != null && left!=null){
            ListNode preNext = pre.next;
            ListNode leftNext = left.next;
            left.next = pre;
            pre.next = leftNext;
            pre = preNext;
            left = leftNext;
        }
        
    }
}

If we can use other space, Use a list to save all node, the change their next node. Like following.

import java.util.*;
public class Solution {
    public void reorderList(ListNode head) {
        ArrayList<ListNode> list = new ArrayList<>();
        ListNode node = head;
        while(node != null){
            list.add(node);
            node = node.next;
        }
        if(list.size() <= 2){
            return;
        }
            
        for(int i = 0; i < list.size()/2; i++){
            list.get(i).next = list.get(list.size()-1-i);
            list.get(list.size()-1-i).next = list.get(i+1);
        }
        list.get(list.size()/2).next = null;
            
    }
}

3. linked-list-cycle-ii

Description

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Follow up:
Can you solve it without using extra space?

Solution
idea

reference: https://www.cnblogs.com/dancingrain/p/3405197.html

Code

without using extra space:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
import java.util.*;
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head, fast = head;
        while(slow!=null && fast!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast){
                break;
            }
        }
        if(slow == null || fast == null || fast.next == null){
            return null;
        }
        ListNode h = head;
        while(h!=slow){
            h = h.next;
            slow = slow.next;
        }
        return h;
    }
}

using extra space:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
import java.util.*;
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ArrayList<ListNode> list = new ArrayList<>();
        while(head!=null){
            if(!list.contains(head)){
                list.add(head);
            }else{
                return head;
            }
            head = head.next;
        }
        return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值