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

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

时间: 2024-11-10 13:57:02

Leetcode刷题笔记(部分非原创)(updating)的相关文章

Leetcode刷题笔记(部分非原创)(131-140题)

139. Word Break leetcode链接:https://oj.leetcode.com/problems/word-break/ DP的思想.设置boolean数组存储,canBreak[i]表示0~i的字符是否满足 public boolean wordBreak(String s, Set<String> dict) { int length = s.length(); boolean[] canBreak = new boolean[length]; for(int i =

【leetcode刷题笔记】String to Integer (atoi)

Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. Notes: It is intended for this problem to be spe

【leetcode刷题笔记】Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

【leetcode刷题笔记】Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example,Given [100, 4, 200, 1, 3, 2],The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should run in

【leetcode刷题笔记】Remove Duplicates from Sorted Array II

Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For example,Given sorted array A = [1,1,1,2,2,3], Your function should return length = 5, and A is now [1,1,2,2,3]. 题解: 设置两个变量:右边kepler和前向游标forward.如果当前kepeler所指的元素和

【leetcode刷题笔记】Restore IP Addresses

Given a string containing only digits, restore it by returning all possible valid IP address combinations. For example:Given "25525511135", return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) 题解:深度优先搜索.用resul

【leetcode刷题笔记】Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. For example:Given the below binary tree and sum = 22, 5 / 4 8 / / 11 13 4 / \ 7 2 1 return true, as t

【leetcode刷题笔记】Insertion Sort List

Sort a linked list using insertion sort. 题解:实现链表的插入排序. 要注意的地方就是,处理链表插入的时候尽量往当前游标的后面插入,而不要往前面插入,后者非常麻烦.所以每次利用kepeler.next.val和head.val比较大小,而不是kepeler.val和head.val比较大小,因为如果用后者,要把head指向的节点插入到kepeler指向的节点的前面,如果kepeler指向的节点是头结点,就更麻烦了. 代码如下: 1 /** 2 * Defi

【leetcode刷题笔记】Max Points on a Line

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. 题解: 思路比较简单,每条直线都可以表示为y=kx+b,所以对于任意三点,如果它们共线,那么它们中任意两点的斜率都相等. 所以就遍历points数组,对其中的每一个元素计算它和位于它后面的数组元素的斜率并保存在一个hashmap中. 这个hashmap的键就是两点构成直线的斜率,值就是和当前元素po