码迷,mamicode.com
首页 > 其他好文 > 详细

Leetcode刷题笔记(部分非原创)(updating)

时间:2015-02-13 13:00:58      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:

1. Two Sum

    最基础的一道题,方法很多,用HashMap存pair是一种(HashSet和HashMap的方法在这里原理是一样的)。也可以sort the whole array first,then use two pointers, one start from the left side, the other from the right side. if array[left]+array[right]>target, move the right index to the left by 1, 小于的话同理. 这里给一个HashMap的方法。

 1 public int[] twoSum(int[] numbers, int target) {
 2    HashMap<Integer, Integer>  map = new HashMap<Integer, Integer>();
 3    int[] result = new int[2];
 4    for(int i = 0; i < numbers.length; i++) {
 5      if(map.containsKey(numbers[i])) {
 6        int index = map.get(numbers[i]);
 7        result[0] = index + 1;
 8        result[1] = i + 1;
 9        break;  
10      } else {
11        map.put(target - numbers[i], i);
12      }   
13    } 
14    return result;          
15 }    

2. Median of Two sorted arrays

    首先,比较暴力的方法是统计两个数组的长度(奇数长度有一个median,偶数长度是最中间的两个数的均值),然后两个数组各设置一个index, 谁小,谁的index++,直到两个index走的总长度达到了median所需的长度。这个是O(n)的复杂度。进一步想,数组里找某个数的问题很容易往binary search上面考。这题也不例外。只不过这道题对于边界的控制需要小心,一下写出bug free的代码还是挺有难度的。

    关键的是把这个问题转化为第k小的问题。只不过最终找的这个k其实是median。转化为第k小的问题有一个好处,比较好设计成一个recursion的函数。recursion,第一步想清楚base case, 这个recursion里面,第k小的数、这个k是可能会变化的。变化到最后,剩下的某个数组为空,或者k==1的时候,就找到了我们想要的结果,recursion就走到头了。第二步想清楚recursion rule。每次判断剩余的A和B两个数组各自的median,通过比较他们的大小,我们要么舍弃A的前半段和B的后半段,要么舍弃A的后半段和B的前半段。每一个情况又分为两种,如果舍弃的是某个数组的后半段,我们要找的仍然是剩下的元素中间的第k小的数,k不变。如果舍弃的是某个数组的前半段,那么我们的k就要发生变化了,传进下一层recursion的k参数就要发生变化。综上,我们实际上每层recursion会分四种情况讨论。具体的我在下面的代码里做了注释。

 1 public double findMedianSortedArrays(int[] A, int[] B) {
 2      int lengthA = A.length;
 3      int lengthB = B.length;
 4      if((lengthA + lengthB) % 2 == 0) {
 5          double r1 = (double)findM(A, 0, lengthA, B, 0, lengthB, (lengthA + lengthB) / 2);
 6          double r2 = (double)findM(A, 0, lengthA, B, 0, lengthB, (lengthA + lengthB) / 2 + 1);
 7          return (r1 + r2) / 2;            
 8     } else {
 9          return findM(A, 0, lengthA, B, 0, lengthB, (lengthA + lengthB) / 2 + 1);
10     }
11 }    
12 
13 public int findM(int[] A, int startA, int endA, int[] B, int startB, int endB, int k) {
14 //转换为第k小数的问题
15     int n = endA - startA;
16     int m = endB - startB;
17     if(n <= 0) {//corner case & base case of recursion
18          return B[startB + k - 1];
19     }     
20     if(m <= 0) {//corner case & base case of recursion
21          return A[startA + k - 1]
22     }
23     if(k == 1) {//corner case & recursion case of recursion
24          return A[startA] < B[startB] ? A[startA] : B[startB];
25     }
26     int midA = (startA + endA) / 2;
27     int midB = (startB + endB) / 2;
28     if(A[midA] <= B[midB]) {// the target will appear at the first half of A, or the second half of B
29          if(n / 2 + m / 2 + 1 >= k) {// if in second half of B, k will not change, because we will not cut any number smaller than target
30               return findM(A, startA, endA, B, startB, midB, k);
31          } else {// if in the first half of A, we will cut all the number in the first half, the next step is: find the (k-n/2-1)th smallest number
32               return findM(A, mid + 1, endA, B, startB, endB, k - n / 2 - 1);
33      } else {
34          if(n / 2 + m / 2 + 1 >= k) {
35               return findM(A, startA, midA, B, startB, endB, k);     
36           } else {
37               return findM(A, startA, endA, B, midB + 1, endB, k - m / 2 -1);
38          }
39     }
40 }           

3. Longest Substring Without Repeating Characters

 

 

 

 

 

 
 
 

Leetcode刷题笔记(部分非原创)(updating)

标签:

原文地址:http://www.cnblogs.com/jianghewade/p/4290007.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!