leetcode刷题记录三

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Viscu/article/details/81983493
1.binary-tree-inorder-traversal

Given a binary tree, return the inorder traversal of its nodes’ values.
For example:
Given binary tree{1,#,2,3},

1
\
2
/
3

return[1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
confused what”{1,#,2,3}”means? > read more on how binary tree is serialized on OJ.
左-根-右 递归

import java.util.ArrayList;
public class Solution {
    ArrayList<Integer> ans;
    public ArrayList<Integer> inorderTraversal(TreeNode root) {
        if(root==null){
            return new ArrayList<Integer>();
        }
        ans=new ArrayList<Integer>();
        dfs(root);
        return ans;
    }

    private void dfs(TreeNode root){
        if(root.left!=null){
            dfs(root.left);
        }
        ans.add(root.val);
        if(root.right!=null){
            dfs(root.right);
        }
    }
}
2.unique-binary-search-trees-ii

Given n, generate all structurally unique BST’s (binary search trees) that store values 1…n.
For example,
Given n = 3, your program should return all 5 unique BST’s shown below.

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3

confused what”{1,#,2,3}”means? > read more on how binary tree is serialized on OJ.
思路:首先呢,我们需要上一题的思路,即确定根节点,那么左边可以有i个节点,
右边可以有n-i-1个节点。搜索一遍即可。

class _70{
    public ArrayList<TreeNode> generateTrees(int n) {
        return dfs(1,n);
    }
    public ArrayList<TreeNode> dfs(int l,int r){
        ArrayList<TreeNode> ans=new ArrayList<TreeNode>();
        if(l>r){
            ans.add(null); //确保不会抛出空指针异常
            return ans;
        }
        for (int i = l; i <= r; i++) { 
            ArrayList<TreeNode> lChild=dfs(l,i-1); //取左边的所有集合
            ArrayList<TreeNode> rChild=dfs(i+1,r); //取右边的所有集合
            for (int j = 0; j < lChild.size(); j++) {  //l.size()*r.size()种情况
                for (int k = 0; k < rChild.size(); k++) { 
                    TreeNode cur=new TreeNode(i); //由于是1...n,那么根节点的值即有i决定。
                    cur.left=lChild.get(j);
                    cur.right=rChild.get(k);
                    ans.add(cur);
                }
            }
        }
        return ans;
    }
}
3.reverse-linked-list-ii

Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given1->2->3->4->5->NULL, m = 2 and n = 4,
return1->4->3->2->5->NULL.
Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.

class _71{
    public ListNode reverseBetween(ListNode head, int m, int n) {
        if(head==null){
            return null;
        }
        ListNode dummy=new ListNode(-1); //用一个傀儡链表存储结果
        dummy.next=head;
        ListNode pre=dummy;
        for (int i = 0; i < m-1; i++) { //走到目标m的前一个 
            pre=pre.next;
        }
        ListNode preHead=pre; 
        ListNode curHead=pre.next;
        ListNode cur=curHead; 
        for (int i = 0; i <= n-m; i++) { //翻转
            ListNode next=cur.next;
            cur.next=pre;
            pre=cur;
            cur=next;
        }
        preHead.next=pre;
        curHead.next=cur;
        return dummy.next;
    }
}
4.remove-duplicates-from-sorted-list

Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given1->1->2, return1->2.
Given1->1->2->3->3, return1->2->3.

class _72{
    public ListNode deleteDuplicates(ListNode head) {
        ListNode cur=head;
        ListNode pre=null;
        while (cur!=null){
            if(pre!=null&&pre.val==cur.val){
                pre.next=cur.next;
                cur=cur.next;
            }else{
                pre=cur;
                cur=cur.next;
            }
        }
        return head;
    }
}
5.remove-duplicates-from-sorted-list-ii

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given1->2->3->3->4->4->5, return1->2->5.
Given1->1->1->2->3, return2->3.

public ListNode deleteDuplicates(ListNode head) {
        ListNode dummy=new ListNode(-1);  //傀儡链表存结果
        dummy.next=head;
        ListNode cur=head;
        ListNode pre=dummy;
        while (cur!=null&&cur.next!=null){
            if(cur.val!=cur.next.val){ //该值可以直接存
                pre=cur;  
            }else{
                while (cur.next!=null&&cur.val==cur.next.val){ //跳过重复值部分。
                    cur=cur.next;
                }
                pre.next=cur.next; 
            }
            cur=cur.next;
        }
        return dummy.next;
    }
6.sqrtx

Implementint sqrt(int x).
Compute and return the square root of x.
二分,注意可能溢出,用long.

public class Solution {
    public int sqrt(int x) {
        int l=0;
        int r=x;
        while (l<=r){
            long mid=l+(r-l)/2;
            long pow2=mid*mid;
            if(pow2==x){
                return (int) mid;
            }else if(pow2>x){
                r=(int) mid-1;
            }else {
                l=(int) mid+1;
            }
        }
        return r;
    }
}
7.merge-two-sorted-lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
顺序比较一下即可。

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy=new ListNode(Integer.MIN_VALUE);
        ListNode cur=dummy;
        while (l1!=null&&l2!=null){
            if(l1.val<l2.val){
                cur.next=l1;
                l1=l1.next;
            }else{
                cur.next=l2;
                l2=l2.next;
            }
            cur=cur.next;
        }
        if(l1==null){
            cur.next=l2;
        }else{
            cur.next=l1;
        }
        return dummy.next;
    }
8.reverse-integer

Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321
click to show spoilers.

public class Solution {
    public int reverse(int x) {
        if(x==0){
            return 0;
        }
        int flag=1;
        int ed=0;
        if(x<0){
            flag=-1;
            ed=1;
        }
        String s=String.valueOf(x);
        char[] chars=s.toCharArray();
        StringBuilder sb=new StringBuilder();
        for (int i = chars.length-1; i >= ed; i--) {
            if(chars[i]=='0'&&i==chars.length-1){
                while (chars[--i]=='0');
                ++i;
            }else{
                sb.append(chars[i]);
            }
        }
        try{  //溢出异常
            res=Integer.valueOf(sb.toString())*flag;
        }catch (Exception e){
            return 0;
        }
        return res;
    }
}
9.palindrome-number

Determine whether an integer is a palindrome. Do this without extra space.
click to show spoilers.
Some hints:
Could negative integers be palindromes? (ie, -1)
If you are thinking of converting the integer to string, note the restriction of using extra space.
You could also try reversing an integer. However, if you have solved the problem “Reverse Integer”, you know that the reversed integer might overflow. How would you handle such case?
There is a more generic way of solving this problem.

public class Solution {
    public boolean isPalindrome(int x) {
        if(x%10==0&&x/10!=0||x<0){
            return false;
        }
        long dummy=0; //考虑溢出
        int t=x;
        while (t>0){
            dummy=dummy*10+t%10;
            t/=10;
        }
        return dummy==x;
    }
}
10.swap-nodes-in-pairs

Given a linked list, swap every two adjacent nodes and return its head.
For example,
Given1->2->3->4, you should return the list as2->1->4->3.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

public class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        ListNode dummy=new ListNode(-1); //保存结果
        ListNode pre=dummy;
        ListNode cur=head;
        while (cur!=null&&cur.next!=null){
            ListNode next=cur.next;  // 1 2 3 4 next2 cur为1 pre为-1
            cur.next=next.next;  // 1->3
            next.next=cur;  // 2->1->3
            pre.next=next; // -1->2->1->3
            pre=cur;  // 2
            cur=cur.next; //3
        }
        return dummy.next;
    }
}
11.remove-nth-node-from-end-of-list

Given a linked list, remove the n th node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
法二:用两个指针,先让快指针走n步,然后让慢指针和快指针走一样的步数,直至快指针走完,那么慢指针所在结点就是倒数第n个结点。

public class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy=new ListNode(-1);
        dummy.next=head;
        int c=0;
        ListNode pre=dummy;
        ListNode cur=head;
        while (cur!=null){
            ++c;
            cur=cur.next;
        }
        cur=head;
        for (int i = 0; i < c-n; i++) {
            pre=cur;
            cur=cur.next;
        }
        pre.next=cur.next;
        return dummy.next;
    }
}
法二:
public class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy=new ListNode(-1);
        dummy.next=head;
        ListNode quick=dummy;
        while (--n>=0){
            quick=quick.next;
        }
        ListNode slow=dummy;
        while (quick.next!=null){
            slow=slow.next;
            quick=quick.next;
        }
        slow.next=slow.next.next;
        return dummy.next;
    }
}
12.merge-k-sorted-lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
归并排序,链表两两归并。

public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if(lists.size()==0){
            return null;
        }
        return solve(lists,0,lists.size()-1);
    }
    //归并
    private ListNode solve(ArrayList<ListNode> lists,int l,int r){
        if(l>=r){
            return lists.get(l);
        }
        int mid=l+(r-1)>>1;
        ListNode left=solve(lists,l,mid);
        ListNode right=solve(lists,mid+1,r);
        return merge(left,right);
    }
    private ListNode merge(ListNode l,ListNode r){
        ListNode dummy=new ListNode(-1);
        ListNode pre=dummy;
        while (l!=null&&r!=null){
            if(l.val>r.val){
                pre.next=r;
                r=r.next;
            }else{
                pre.next=l;
                l=l.next;
            }
            pre=pre.next;
        }
        if(l==null){
            pre.next=r;
        }else{
            pre.next=l;
        }
        return dummy.next;
    }
}
// 两两合并
class _81{
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if(lists.size()==0){
            return null;
        }
        ListNode head=lists.get(0);
        for (int i = 1; i < lists.size(); i++) {
            head=merge(head,lists.get(i));
        }
        return head;
    }
    private ListNode merge(ListNode l,ListNode r){
        ListNode dummy=new ListNode(-1);
        ListNode pre=dummy;
        while (l!=null&&r!=null){
            if(l.val>r.val){
                pre.next=r;
                r=r.next;
            }else{
                pre.next=l;
                l=l.next;
            }
            pre=pre.next;
        }
        if(l==null){
            pre.next=r;
        }else{
            pre.next=l;
        }
        return dummy.next;
    }
}
13.reverse-nodes-in-k-group

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed
For example,
Given this linked list:1->2->3->4->5
For k = 2, you should return:2->1->4->3->5
For k = 3, you should return:3->2->1->4->5

public class _82 {
    public ListNode reverseKGroup(ListNode head, int k) {
        if(head==null||head.next==null||k<2){
            return head;
        }
        ListNode dummy=new ListNode(-1);
        dummy.next=head;
        ListNode quick=dummy;
        ListNode slow=dummy;
        while (true){
            int m=k;
            while (quick!=null&&--m>=0){  //已到第n*k个位置
                quick=quick.next;
            }
            if(quick!=null){ //进行翻转
                head=slow.next; // -1->1->2->3->4    k:3
                while (slow.next!=quick){ 
                    ListNode temp=slow.next;  
                    slow.next=temp.next;
                    temp.next=quick.next;
                    quick.next=temp;
                } // -1->2->3->1->4  ->  -1->3->2->1->4  
                slow=head;
                quick=head;
            }else {
                break;
            }
        }
        return dummy.next;
    }
}
14.search-insert-position

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.
Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
二分找第一个大于等于target的值的位置,记得把r置为A.len,而不是A.len-1.

public int searchInsert(int[] A, int target) {
        return lower_bound(A,target);
    }
    private int lower_bound(int[] A,int target){
        int l=0;
        int r=A.length;
        while (l<r){
            int mid=l+(r-l)/2;
            if(A[mid]==target){
                return mid;
            }else if(target>A[mid]){
                l=mid+1;
            }else {
                r=mid;
            }
        }
        return l;
    }

15.longest-valid-parentheses

Given a string containing just the characters’(‘and’)’, find the length of the longest valid (well-formed) parentheses substring.
For”(()”, the longest valid parentheses substring is”()”, which has length = 2.
Another example is”)()())”, where the longest valid parentheses substring is”()()”, which has length = 4.

import java.util.Stack;
public class Solution {
    public int longestValidParentheses(String s) {
        if(s.equals("")){
            return 0;
        }
        int max=0;
        int index=-1;
        Stack<Integer> stack=new Stack<Integer>();
        for (int i = 0; i < s.length(); i++) {
            if(s.charAt(i)=='('){ //遇到(压入栈中
                stack.push(i);
            }else{
                if (stack.isEmpty()){ //如果栈为空且当前括号为),那么我们就更新下标
                    index=i; //因为i之前已经用过了且已经不符合条件,我们需要更新符合条件的串的开始位置
                }else{
                    stack.pop(); //不为空,即可以匹配,我们将可以匹配的()弹出,并更新最大值
                    if(stack.isEmpty()){ //若为null,则max=i-index
                        max=Math.max(max,i-index);
                    }else{  
                        max=Math.max(max,i-stack.peek());  //这种情况就有是(()())的
                    }
                }
            }
        }
        return max;
    }
}
16.jump-game

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A =[2,3,1,1,4], returntrue.
A =[3,2,1,0,4], returnfalse.
用一个最大优先队列维护当前能走到的最大坐标值,
遇到0的坐标话,我们优先队列最大值与之坐标比,若小于等于,则返回false,否则,继续。

import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution {
     public boolean canJump(int[] A) {
        PriorityQueue<Integer> it=new PriorityQueue<Integer>( A.length, new Comparator<Integer>() {
            @Override
            public int compare(Integer integer, Integer t1) {
                return t1-integer;
            }
        } );
        for (int i = 0; i < A.length-1; i++) {
            if(A[i]==0){
                if(it.size()>0&&it.peek()<=i){
                    return false;
                }
                if(it.size()==0){
                    return false;
                }
            }else {
                it.add(i+A[i]);
            }
        }
        return true;
    }
}
17.rotate-list

Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given1->2->3->4->5->NULLand k =2,
return4->5->1->2->3->NULL.
考虑k>len,所以我们可以把链表首尾相连成环,在移动len-k%len个位置即为结果。

public class Solution {
    public ListNode rotateRight(ListNode head, int n) {
        if(head==null||head.next==null||n==0){
            return head;
        }
        int total=1;
        ListNode cur=head;
        while (cur.next!=null){ //先统计list的长度
            cur=cur.next;
            ++total;
        }
        cur.next=head; //首尾相连
        cur=head;
        int k=total-n%total; //我们算出应该移动的步数 {1,2} k=3 所以应该移动1步,再断开环。 
        for (int i = 1; i < k; i++) {
            cur=cur.next;
        }
        head=cur.next; 
        cur.next=null; 
        return head;
    }
}
18.powx-n

Implement pow(x, n).
快速幂做。

public double pow(double x, int n) {
        boolean flag=false;
        if(n<0){
            n*=-1;
            flag=true;
        }
        double ans=1; 
        while (n>0){  //快速幂
            if((n&1)==1){
                ans*=x;
            }
            x*=x;
            n>>=1;
        }
        if(flag){
            return 1/ans;
        }
        return ans;
    }

19、

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
deepCopy,这里难的不是next指针的复制,难的是Random指针的复制,
如果单纯是next,我们跑一便即可,
这里我们就需要做一些处理了。

public class Solution {
    public RandomListNode copyRandomList(RandomListNode head) {
        if(head==null){
            return null;
        }
        RandomListNode copy;
        RandomListNode cur=head;
        while (cur!=null){
            copy=new RandomListNode(cur.label); //新建的节点
            copy.next=cur.next; //我们把新建节点插在旧的节点之间  例如 1->2->null 1->1->2->2->null
            cur.next=copy;
            cur=copy.next;
        }
        cur=head;
        while (cur!=null){  //进行random指针的复制
            if(cur.random!=null){ //不为空
                cur.next.random=cur.random.next; //random指针指向的旧节点的下一个节点即为该旧节点的复制节点。
            }
            cur=cur.next.next;
        }
        cur=head; //现在head还是原来的list
        head=cur.next; //现在的head已经是新的list,进行操作不影响原来的list对象
        copy=head;
        while (cur!=null){
            cur=copy.next;
            if(cur!=null){
                copy.next=cur.next;
                copy=cur.next;
            }
        }
        return head;
    }
}
20.merge-sorted-array

Given two sorted integer arrays A and B, merge B into A as one sorted array.
Note:
You may assume that A has enough space to hold additional elements from B. The number of elements initialized in A and B are m and n respectively.
两个有序的数组,而且A数组足够容纳B数组的元素,那么我们就从n+m-1开始从后往前以此比较各个元素。

class _90{
    public void merge(int A[], int m, int B[], int n) {
        int total=m+n-1;
        while (m>0&&n>0){
            A[total--]=(A[m-1]>=B[n-1]?A[--m]:B[--n]);
        }
        for(int i=0;i<n;A[i]=B[i++]);
    }
}

猜你喜欢

转载自blog.csdn.net/Viscu/article/details/81983493
今日推荐