leetcode刷题

Posted 温暖的向阳花

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode刷题相关的知识,希望对你有一定的参考价值。

2017/3/1

215. Kth Largest Element in an Array

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note: 
You may assume k is always valid, 1 ≤ k ≤ array\'s length.
View Code

自己的代码:

/**
* 先利用Arrays的sort()函数对给定的数组进行排序,
* 得到的数组是升序排列的,然后获得数组的长度,重新申请一个新的数组,
* 将之前的数组从最后一个开始,一次存入新数组的第一个位置开始,
* 这样新的数组就成了降序排列,这是返回数组当中的第k个位置的数值即可
* @param nums
* @param k
* @return
*/

public class Solution {
    public int findKthLargest(int[] nums, int k) {
        Arrays.sort(nums);
        int n=nums.length;
        int[] res=new int[n];
        for(int i=nums.length-1,j=0;i>=0;i--,j++) {
            res[j]=nums[i];
        }
        return res[k-1];
    }
}
View Code

另一种解法是利用PriorityQueue,关于priorityQueue的使用详情,博客如下http://www.cnblogs.com/CarpenterLee/p/5488070.html,具体代码如下:

class Solution {
    /**
     * @return
     */
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> largek = new PriorityQueue<Integer>();
        for (int i : nums) {
            largek.add(i);
            if (largek.size() > k) {
                largek.poll();
            }
        }
        return largek.poll();
    }
};
View Code

最优解:O(N lg N) running time + O(1) memory

public int findKthLargest(int[] nums, int k) {
        final int N = nums.length;
        Arrays.sort(nums);
        return nums[N - k];
}
View Code

 

---------------------------------------------------------------------------------------------------------------------------------

2017/3/2

150. Evaluate Reverse Polish Notation

Evaluate the value of an arithmetic expression in Reverse Polish Notation.

Valid operators are +, -, *, /. Each operand may be an integer or another expression.

Some examples:
  ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
  ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6
View Code

关于Stack的具体介绍见博客:http://www.cnblogs.com/skywang12345/p/3308852.html

自己的代码:

public class Solution {
    /**
     * Author: wanghaibo
     * Complexity Time: O(n); Space: O(n)
     * Explaination: 利用Stack实现,首先遍历tokens数组,
     * 如果字符串不是操作符是数字,则进栈,如果是操作符,则将两个
     * 数字出栈,根据操作符得到结果后重新压入栈
     * @param tokens
     * @return
     */
    public int evalRPN(String[] tokens) {
        if (tokens.length == 1) {
            return Integer.parseInt(tokens[0]);
        }
        Stack<String> stack = new Stack<String>();
        for (String i : tokens) {
            if (isoperator(i) != 0) {
                int a = Integer.parseInt(stack.pop());
                int b = Integer.parseInt(stack.pop());
                String c = "";
                if (i.equals("+")) {               
                    c = String.valueOf(b + a);
                } else if (i.equals("-")) {
                    c = String.valueOf(b - a);
                } else if (i.equals("*")) {
                    c = String.valueOf(a * b);
                } else if (i.equals("/")) {
                    c = String.valueOf(b / a);
                }
                stack.push(c);
            } else {
                stack.push(i);
            }
        }
        return Integer.parseInt(stack.pop());
    }
    public int isoperator(String s) {
        if (s.equals("+")) {
            return 1;
        } else if (s.equals("-")) {
            return 2;
        } else if (s.equals("*")) {
            return 3;
        } else if (s.equals("/")) {
            return 4;
        }else {
            return 0;
        }
    }
}
View Code

最优解:

import java.util.Stack;

public class Solution {
    public int evalRPN(String[] tokens) {
        int a,b;
        Stack<Integer> S = new Stack<Integer>();
        for (String s : tokens) {
            if(s.equals("+")) {
                S.add(S.pop()+S.pop());
            }
            else if(s.equals("/")) {
                b = S.pop();
                a = S.pop();
                S.add(a / b);
            }
            else if(s.equals("*")) {
                S.add(S.pop() * S.pop());
            }
            else if(s.equals("-")) {
                b = S.pop();
                a = S.pop();
                S.add(a - b);
            }
            else {
                S.add(Integer.parseInt(s));
            }
        }    
        return S.pop();
    }
}
View Code

 

----------------------------------------------------------------------------------------------------------------------------------------

2017/3/5

373. Find K Pairs with Smallest Sums

You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.

Define a pair (u,v) which consists of one element from the first array and one element from the second array.

Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.

Example 1:
Given nums1 = [1,7,11], nums2 = [2,4,6],  k = 3

Return: [1,2],[1,4],[1,6]

The first 3 pairs are returned from the sequence:
[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
Example 2:
Given nums1 = [1,1,2], nums2 = [1,2,3],  k = 2

Return: [1,1],[1,1]

The first 2 pairs are returned from the sequence:
[1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
Example 3:
Given nums1 = [1,2], nums2 = [3],  k = 3 

Return: [1,3],[2,3]

All possible pairs are returned from the sequence:
[1,3],[2,3]
View Code

先声明一个优先队列,重写compare()函数,实现大顶堆,然后依次入堆,构造一个大顶堆。然后声明一个LinkedListed,将大顶堆根插入双向链表中,注意k,只需要插入k个就行,如果小于k个,直接返回,代码如下:

    public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        List<int[]> res = new LinkedList<>();
        Queue<int[]> queue = new PriorityQueue<>(k,new Comparator<int[]>(){
            public int compare(int[] o1,int[] o2){
                int tmp1 = o1[0]+o1[1];
                int tmp2 = o2[0]+o2[1];

                return tmp1 - tmp2;
            }            
        });
       for(int i = 0;i<nums1.length;i++){
           for(int j = 0;j<nums2.length;j++){
               queue.add(new int[]{nums1[i],nums2[j]});
           }
       }
       while(k-->0){
           int[] tmp = queue.poll();
           if(tmp == null)
                break;
            res.add(tmp);
       }
       return res;
    }
View Code

需要了解LinkedList,具体链接http://www.cnblogs.com/chenssy/p/3514524.html,做不出来主要是因为不了解LinekedList和PriorityQueue,需要多看!!!

最优解:

Basic idea: Use min_heap to keep track on next minimum pair sum, and we only need to maintain K possible candidates in the data structure.

Some observations: For every numbers in nums1, its best partner(yields min sum) always strats from nums2[0] since arrays are all sorted; And for a specific number in nums1, its next candidate sould be [this specific number] + nums2[current_associated_index + 1], unless out of boundary;)

Here is a simple example demonstrate how this algorithm works.

image

The run time complexity is O(kLogk) since que.size <= k and we do at most k loop.

public class Solution {
    public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        PriorityQueue<int[]> que = new PriorityQueue<>((a,b)->a[0]+a[1]-b[0]-b[1]);
        List<int[]> res = new ArrayList<>();
        if(nums1.length==0 || nums2.length==0 || k==0) return res;
        for(int i=0; i<nums1.length && i<k; i++) que.offer(new int[]{nums1[i], nums2[0], 0});
        while(k-- > 0 && !que.isEmpty()){
            int[] cur = que.poll();
            res.add(new int[]{cur[0], cur[1]});
            if(cur[2] == nums2.length-1) continue;
            que.offer(new int[]{cur[0],nums2[cur[2]+1], cur[2]+1});
        }
        return res;
    }
}
View Code

------------------------------------------------------------------------------------------------------------------------------------------------

2017/3/6

202. Happy Number

Write an algorithm to determine if a number is "happy".

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

Example: 19 is a happy number

12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
View Code

代码如下:

    /**
     * 或得一个数每一位的平方相加之和
     * @param n
     * @return
     */
    public int squaresum(int n) {
        int sum = 0, tmp;
        while (n != 0) {
            tmp = n % 10;
            sum +=tmp * tmp;
            n /= 10;
        }
        return sum;
    }
    /**
     * 将中间结果存入HashSet,如果发现结果为1,则返回true,如果结果中出现了n,则代表
     * 出现环,返回false,否则就将中间结果存入set中
     * @param n
     * @return
     */
    public boolean isHappy(int n) {
        if (n <= 0) return false;
        Set<Integer> set = new HashSet<Integer>();
        set.add(n);
        while(true) {
            n = squaresum(n);
            if (n == 1)
                return true;
            else if (set.contains(n))
                return false;
            else set.add(n);
        }
    }
View Code

另一种解法是用快慢指针,代码如下:

/**
     * 或得一个数每一位的平方相加之和
     * @param n
     * @return
     */
    public int squaresum(int n) {
        int sum = 0, tmp;
        while (n != 0) {
            tmp = n % 10;
            sum +=tmp * tmp;
            n /= 10;
        }
        return sum;
    }
    /**
     * 新建一个快指针和一个慢指针
     * 慢指针只求一次,下一个数;块指针每次求两次,下一个数
     * 如果快指针的值和慢指针的值相等,则返回false
     * 快指针的值等于1,则返回true
     * @param n
     * @return
     */
    public boolean isHappy(int n) {
        int slow = n;
        int fast = n;
        while(true) {
            slow = squaresum(slow);
            fast = squaresum(squaresum(fast));
            if (fast == 1)
                return true;
            if (slow == fast)
                return false;
        }
    }
View Code

---------------------------------------------------------------------------------------------------------------------------------------

2017/3/7

263. Ugly Number

Write a program to check whether a given number is an ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7.

Note that 1 is typically treated as an ugly number.
View Code

代码如下:

    /**
     * 首先判断输入的数据是否小于等于0,如果是,则肯定不是ugly数,返回false
     * 判断是不是1,是的话肯定是ugly数
     * 否则
     * 如果能对2,3,5进行整除,则用num除以2,3,5,只要num>1时,循环进行
     * 否则返回false
     * @param num
     * @return
     */
    public boolean isUgly(int num) {
        if (num <= 0) {
            return false;
        }
        if (num == 1) {
            return true;
        }
        while (num > 1) {
            if (num % 2 == 0) {
                num /= 2;
            }
            else if (num % 3 == 0) {
                num /= 3;
            }
            else if (num % 5 == 0) {
                num /= 5;
            }
            else {
                return false;
            }
        }
        return true;
    }
View Code

最优解与以上类似,代码如下:

public boolean isUgly(int num) {
    if (num <= 0) {return false;}
    if (num == 1) {return true;}
    if (num % 2 == 0) {
        return isUgly(num/2);
    }
    if (num % 3 == 0) {
        return isUgly(num/3);
    }
    if (num % 5 == 0) {
        return isUgly(num/5);
    }
    return false;
}
View Code

-------------------------------------------------------------------------------------------------------------------------------------------------

2017/3/8

264. Ugly Number II

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number, and n does not exceed 1690.
View Code

代码如下:

public class Solution {
    /**
     * 首先将1加入到集合当中,设置三个指针,分别取出三个指针对应的list
     * 中的值,分别向相关的数,挑选最小的一个数作为下一个Ugly数,加入
     * list中,只有最小的数对应的那个指针才进行+1操作
     * 最后返回第n个数
     * @param n
     * @return
     */
    public int nthUglyNumber(int n) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        int p2 = 0;
        int p3 = 0;
        int p5 = 0;
        while (list.size() < n) {
            int ugly2 = list.get(p2) * 2;
            int ugly3 = list.get(p3) * 3;
            int ugly5 = list.get(p5) * 5;
            int min = Math.min(ugly2, Math.min(ugly3, ugly5));
            list.add(min);
            if (min == ugly2) p2++;
            if (min == ugly3) p3++;
            if (min == ugly5) p5++;
        }
        return list.get(n-1);
    }
}
View Code

最优解和解析如下:

The idea of this solution is from this page:http://www.geeksforgeeks.org/ugly-numbers/

The ugly-number sequence is 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …
because every number can only be divided by 2, 3, 5, one way to look at the sequence is to split the sequence to three groups as below:

(1) 1×2, 2×2, 3×2, 4×2, 5×2, …
(2) 1×3, 2×3, 3×3, 4×3, 5×3, …
(3) 1×5, 2×5, 3×5, 4×5, 5×5, …
We can find that every subsequence is the ugly-sequence itself (1, 2, 3, 4, 5, …) multiply 2, 3, 5.

Then we use similar merge method as merge sort, to get every ugly number from the three subsequence.

Every step we choose the smallest one, and move one step after,including nums with same value.

Thanks for this author about this brilliant idea. Here is my java solution

public class Solution {
    public int nthUglyNumber(int n) {
        int[] ugly = new int[n];
        ugly[0] = 1;
        int index2 = 0, index3 = 0, index5 = 0;
        int factor2 = 2, factor3 = 3, factor5 = 5;
        for(int i=1;i<n;i++){
            int min = Math.min(Math.min(factor2,factor3),factor5);
            ugly[i] = min;
            if(factor2 == min)
                factor2 = 2*ugly[++index2];
            if(factor3 == min)
                factor3 = 3*ugly[++index3];
            if(factor5 == min)
                factor5 = 5*ugly[++index5];
        }
        return ugly[n-1];
    }
}
View Code

----------------------------------------------------------------------------------------------------------------------------------------------

 2017/3/14

278. First Bad Version

You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.

Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad.

You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.
View Code

利用二分查找,最优代码如下:

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int lo = 1, hi = n;
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            if (isBadVersion(mid)) {
                hi = mid - 1;
            } else {
                lo = mid + 1;
            }
        }
        return lo;
    }
}
View Code

-----------------------------------------------------------------------------------------------------------------------------------------------

2017/3/16

74. Search a 2D Matrix

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.
For example,

Consider the following matrix:

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
Given target = 3, return true.
View Code

解法一如下:

/**
     * 遍历每一行,对每一行进行二分查找,假设有m行n列,则算法的时间复杂度为mlog(n)
     * @param matrix
     * @param target
     * @return
     */
    public boolean searchMatrix(int[][] matrix, int target) {
        boolean flag = false;
        if (matrix.length == 0 || matrix == null || matrix[0] == null || matrix[0].length ==0) {
            return false;
        }
        for (int i = 0; i < matrix.length; i++) {
            int lo = 0;
            int n = matrix[i].length;
            int hi = n - 1;
            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if (matrix[i][mid] == target) {
                    flag = true;
                    break;
                }
                if (matrix[i][mid] > target) {
                    hi = mid - 1;
                }
                if (matrix[i][mid] < target) {
                    lo = mid + 1;
                }
            }
        }
        return flag;
        
    }
View Code

解法二如下:

    /**
     * 从左下角开始查找,如果target小于这个数,则行数减一,如果大于这个数,则列数加一
     * 时间复杂度为O(m)+O(n),m为行数,n为列数
     * @param matrix
     * @param target
     * @return
     */
    public boolean searchMatrix(int[][] matrix, int target) {
        boolean flag = false;
        if (matrix.length == 0 || matrix == null || matrix[0] == null || matrix[0].length == 0) {
            return false;
        }
        int m = matrix.length;
        int n = matrix[0].length;
        int i = m - 1;
        int j = 0;
        while (i >= 0 && j < n) {
            if (matrix[i][j] < target) {
                j++;
            } else if (matrix[i][j] > target) {
                i--;
            } else {
                flag = true;
                break;
            }
        }
        return flag;
    }
View Code

解法三如下:

    /**
     * 由于数组是有序递增的,那么可以把二维数组转换为一位数组进行操作
     * 假设二维数组每一行有n列,那么一位数组中下标为x的数对应的二维数组中
     * 的数的为matrix[x/n][x%n],利用二分法对一维数组进行查找即可
     * 时间复杂度为O(log(m*n))
     * @param matrix
     * @param target
     * @return
     */
    public boole

以上是关于leetcode刷题的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode刷题笔记-数据结构-day16

LeetCode刷题笔记-数据结构-day5

LeetCode刷题笔记-数据结构-day20

LeetCode刷题笔记-数据结构-day12

LeetCode刷题笔记-数据结构-day12

LeetCode刷题笔记-动态规划-day4