版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bw_yyziq/article/details/79840996
[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;
}
}