1. 程式人生 > >leetcode 144 145 二叉樹的遍歷 141 142 環狀連結串列 149 窮舉法

leetcode 144 145 二叉樹的遍歷 141 142 環狀連結串列 149 窮舉法

[144] binary-tree-preorder-traversal 二叉樹的前序遍歷

使用棧,不用遞迴

/**
 * 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<TreeNode>();
        stack.push(root);
        
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            preorder.add(node.val);
            if(node.right != null) stack.push(node.right);
            if(node.left != null) stack.push(node.left);
        }
        
        return preorder;
    }
}

[145] binary-tree-postorder-traversal 二叉樹的後續遍歷

同樣是使用棧,這麼做會改變二叉樹的結構,如果不想改變,需要額外記憶體用來將二叉樹複製一份。

/**
 * 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> postorderTraversal(TreeNode root) {
        
        ArrayList<Integer> postorder = new ArrayList<Integer>();
        if(root == null) return postorder;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        
        while(!stack.isEmpty()){
            TreeNode node = stack.peek();
            if(node.left == null && node.right == null) {
                stack.pop();
                postorder.add(node.val);
            }
            if(node.right != null) stack.push(node.right);
            if(node.left != null) stack.push(node.left);
            
            node.left = null;
            node.right = null;
        }
        
        return postorder;
        
    }
}

[141] linked-list-cycle

快慢指標相遇則有環,快指標能變成null則無環。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        
        if(head == null) return false;
        
        ListNode fast = head;
        ListNode slow = head;
        
        while(fast.next != null && fast.next.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) return true;
        }
        return false;
    }
}

[142] linked-list-cycle-ii

有如下結論:

a從快慢指標相遇的點出發每次走一步,b從頭出發每次走一步,a,b會在環開始的節點相遇。

由此則得程式碼如下

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

[149] max-points-on-a-line 窮舉法

這道題普遍有兩種做法,一種是先取出兩個點組成一條直線,再檢測其餘的點有多少個在這條直線上,找出最大的那條直線,由於巢狀三層迴圈,演算法的時間複雜度為O(n^3)。程式碼很好實現。且可以用乘法判斷是否共線,因此不會出現由於浮點數的精度問題導致的不準確情況。

另一種是先選取一個點作為基點,然後計算其餘各點與這個點確定的斜率,斜率相同則視為在同一條直線上,維護一個map,鍵值對為 斜率-點的個數。但是在計算斜率時,由於精度問題,有可能會出現及其相似但不相同的斜率無法辨別的情況。

比如輸入:[[0,0],[94911151,94911150],[94911152,94911151]] ,則無法辨別從而導致認為三點共線。

第二種演算法實現:(leetcode無法通過,牛客網可以通過)

import java.util.*;

public class Solution {
    public int maxPoints(Point[] points) {

        if(points.length < 3) return points.length;

        int a,b,x,y;
        double k;
        int max = 1;
        for (int j = 0; j < points.length ; j++) {
            a = points[j].x;
            b = points[j].y;
            int same =0;
            Map<Double,Integer> map = new HashMap<Double,Integer>();
            for(int i = 0;i < points.length;i++){
                if(i == j) continue;
                x = points[i].x;
                y = points[i].y;
                
                if(a == x && b == y) {
                    same ++;
                    continue;
                };
                if(a == x) k = Integer.MAX_VALUE;
                else if(b == y) k = 0;
                else k = (double)(y - b)/(double)(x - a);
                if(map.containsKey(k)) map.put(k,map.get(k) + 1);
                else map.put(k,2);
            }
            int temp = 1;
            for(Integer value : map.values()){
                temp = Math.max(temp,value);
            }
            max = Math.max(temp + same,max);
        }
        return max;
    }
}