您的位置:首页 > 其它

Leetcode题解(二)

2018-03-26 10:17 246 查看

1.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> list=new ArrayList<>();
if(root==null)
return list;
postorder(root,list);
return list;

}
private static void postorder(TreeNode root,ArrayList<Integer> list)//左右根的顺序进行后续遍历,为便于递归,直接重新
{
if(root.left!=null)
postorder(root.left,list);
if(root.right!=null)
postorder(root.right,list);
list.add(root.val);
}

}

2.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.ArrayList;
public class Solution {
public ArrayList<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> result=new ArrayList<>();
if(root==null)
return result;
preorder(root,result);
return result;

}
private static void preorder(TreeNode root,ArrayList<Integer> list)//左右根的顺序进行后续遍历,为便于递归,直接重新
{
list.add(root.val);
if(root.left!=null)
preorder(root.left,list);
if(root.right!=null)
preorder(root.right,list);

}

}

3.reorder-list



        本题主要是的是另类的翻转链表,将后半部分翻转之后再依次插入前半部分两个结点之间即可。主要考察几个知识点,首先是寻找中间结点,从中间结点断开,分为前后两个链表,然后将后面那个链表翻转,最后将后面链表的元素根据要求插入到前面的链表中。实现代码如下:/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
*
4000
val = x;
* next = null;
* }
* }
*/
public class Solution {
public void reorderList(ListNode head) {
ListNode pre=head;
ListNode res;
if(head==null) return;
ListNode slow=head;
ListNode fast=head;
while(fast.next!=null&&fast.next.next!=null)
{
slow=slow.next;
fast=fast.next.next;
}
res=slow.next;//后半段的头指针
slow.next=null;
ListNode temp=null;
ListNode mid;
//翻转链表
while(res!=null)
{
mid=res.next;
res.next=temp;
temp=res;
res=mid;
}
ListNode after=temp;//翻转后的链表

while(pre!=null&&after!=null)
{
ListNode node1=pre.next;
ListNode node2=after.next;
pre.next=after;
after.next=node1;
after=node2;
pre=node1;
}
}

}

4.linked-list-cycle



        这题是判断链表有没有环的问题,不占额外空间且效率比较高的算法是快慢指针的算法,即设置一个快指针一个慢指针,另快指针的速度是慢指针的两倍,然后两个指针都从头结点出发,如果两个指针最终还能相遇,则说明有环。/**
* 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;

}

}

5.linked-list-cycle-ii



        本题在判断如果有环的基础上还需要找到环的入口,那么如下图进行计算:


        首先,快慢指针都从O点出发,假设最终在B点相遇,根据两者速度关系,应该慢指针未满一圈就会被赶上,假设快指针跑了n圈然后在B点与慢指针相遇,两者的路程关系为2*(a+b)=a+b+n*(b+c);最后化简为a=(n-1)*(b+c)+c,所以可以发现如果慢指针运动距离为a的路径,将会回到A点,那么可以将快指针变为慢指针,并从O点出发,原来的慢指针从B点同时出发,最终相遇的地点就是A点,也就是环的入口。实现代码如下:
/**
* 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;
boolean isCircle=false;
while(fast.next!=null&&fast.next.next!=null)
{
fast=fast.next.next;
slow=slow.next;
if(slow==fast)
{
isCircle=true;
break;
}
}
if(isCircle)
{
fast=head;
while(slow!=fast)
{
slow=slow.next;
fast=fast.next;
}
return slow;
}
return null;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: