Skip to content

Commit b5dec91

Browse files
committed
1D
1D
1 parent 384e741 commit b5dec91

File tree

7 files changed

+418
-40
lines changed

7 files changed

+418
-40
lines changed

Array/1D.md

+105-1
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,72 @@ public class Solution {
308308
}
309309
~~~
310310

311+
## 456. 132 Pattern
312+
Given a sequence of n integers a1, a2, ..., an, a 132 pattern is a subsequence ai, aj, ak such that i < j < k and ai < ak < aj. Design an algorithm that takes a list of n numbers as input and checks whether there is a 132 pattern in the list.
313+
314+
Note: n will be less than 15,000.
315+
316+
Example 1:
317+
~~~
318+
Input: [1, 2, 3, 4]
319+
320+
Output: False
321+
322+
Explanation: There is no 132 pattern in the sequence.
323+
~~~
324+
Example 2:
325+
~~~
326+
Input: [3, 1, 4, 2]
327+
328+
Output: True
329+
330+
Explanation: There is a 132 pattern in the sequence: [1, 4, 2].
331+
~~~
332+
Example 3:
333+
~~~
334+
Input: [-1, 3, 2, 0]
335+
336+
Output: True
337+
338+
Explanation: There are three 132 patterns in the sequence: [-1, 3, 2], [-1, 3, 0] and [-1, 2, 0].
339+
~~~
340+
341+
#### Solution
342+
1. O(n^2) method : fix j, find min from range(0, j - 1), check whether in range(j + 1, nums.length - 1) has a number less than nums[j] and greater than min.
343+
2. O(n) method : using stack.
344+
345+
Method 1 O(n^2) <br>
346+
Attempt: 1
347+
~~~
348+
public class Solution {
349+
public boolean find132pattern(int[] nums) {
350+
if (nums == null || nums.length < 3) return false;
351+
352+
// fix j
353+
for (int j = 1; j < nums.length - 1; j++) {
354+
// find min num in range from 0 to j - 1, and make it as i
355+
int min = nums[0];
356+
// int index = 0; // no need to track index
357+
for (int i = 1; i < j; i++) {
358+
if (nums[i] < min) {
359+
min = nums[i];
360+
// index = i;
361+
}
362+
}
363+
364+
// found a valid i
365+
if (min < nums[j]) {
366+
// find k in range from j + 1 to nums.length - 1
367+
for (int k = j + 1; k < nums.length; k++) {
368+
if (nums[k] < nums[j] && nums[k] > min) return true;
369+
}
370+
}
371+
}
372+
373+
return false;
374+
}
375+
}
376+
~~~
311377
## 18. 4Sum (Medium)
312378
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
313379

@@ -462,7 +528,7 @@ Given n non-negative integers a1, a2, ..., an, where each represents a point at
462528
Note: You may not slant the container and n is at least 2.
463529

464530
#### Solution
465-
Two pointers
531+
Two pointers <br>
466532
Old version of code will get TLE with new leetcode test code.
467533
How to improve?
468534

@@ -701,6 +767,44 @@ public class Solution {
701767
~~~
702768

703769
# Binary Search
770+
## 287. Find the Duplicate Number
771+
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
772+
773+
Note:
774+
1. You must not modify the array (assume the array is read only).
775+
2. You must use only constant, O(1) extra space.
776+
3. Your runtime complexity should be less than O(n2).
777+
4. There is only one duplicate number in the array, but it could be repeated more than once.
778+
779+
#### Solution
780+
题目限定只有一个重复的数字让问题变得简单
781+
782+
Attempt: 2 (bug when counting)
783+
~~~
784+
public class Solution {
785+
public int findDuplicate(int[] nums) {
786+
if (nums == null || nums.length == 0) return 0;
787+
int l = 1;
788+
int r = nums.length - 1;
789+
while (l < r) {
790+
int m = (r - l) / 2 + l;
791+
int count = 0;
792+
for (int i = 0; i < nums.length; i++) {
793+
// if (nums[i] <= m) count++; // bug
794+
if (nums[i] >= l && nums[i] <= m) count++;
795+
}
796+
if (count > m - l + 1) {
797+
r = m;
798+
}
799+
else {
800+
l = m + 1;
801+
}
802+
}
803+
return l;
804+
}
805+
}
806+
~~~
807+
704808
## 4. Median of Two Sorted Arrays (Hard) *
705809
There are two sorted arrays nums1 and nums2 of size m and n respectively.
706810

Array/2D.md

+211
Original file line numberDiff line numberDiff line change
@@ -706,3 +706,214 @@ public class NumMatrix {
706706
* int param_2 = obj.sumRegion(row1,col1,row2,col2);
707707
*/
708708
~~~
709+
710+
# Binary Search
711+
## 74. Search a 2D Matrix
712+
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
713+
714+
Integers in each row are sorted from left to right.
715+
The first integer of each row is greater than the last integer of the previous row.
716+
For example,
717+
718+
Consider the following matrix:
719+
~~~
720+
[
721+
[1, 3, 5, 7],
722+
[10, 11, 16, 20],
723+
[23, 30, 34, 50]
724+
]
725+
~~~
726+
Given target = 3, return true.
727+
728+
#### Solution
729+
730+
Attempt: 3 <br>
731+
bug 1: 输入是matrix, 粗心用了nums
732+
bug 2: 在转换成[][]的时候 [m / w][m % w],粗心用了h
733+
bug 3: 传统的二分查找结束的条件是l <= r
734+
~~~
735+
public class Solution {
736+
public boolean searchMatrix(int[][] matrix, int target) {
737+
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;
738+
int h = matrix.length;
739+
int w = matrix[0].length;
740+
int l = 0;
741+
int r = h * w - 1;
742+
while (l <= r) {
743+
int m = (r - l) / 2 + l;
744+
if (target == matrix[m / w][m % w]) return true;
745+
else if (target > matrix[m / w][m % w]) l = m + 1;
746+
else r = m - 1;
747+
}
748+
return false;
749+
}
750+
}
751+
~~~
752+
753+
## 240. Search a 2D Matrix II (Optimal Solution not BS)
754+
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
755+
756+
Integers in each row are sorted in ascending from left to right.
757+
Integers in each column are sorted in ascending from top to bottom.
758+
For example,
759+
760+
Consider the following matrix:
761+
~~~
762+
[
763+
[1, 4, 7, 11, 15],
764+
[2, 5, 8, 12, 19],
765+
[3, 6, 9, 16, 22],
766+
[10, 13, 14, 17, 24],
767+
[18, 21, 23, 26, 30]
768+
]
769+
~~~
770+
Given target = 5, return true.
771+
772+
Given target = 20, return false.
773+
774+
#### Solution
775+
1. Naiive way is to do binary search in each row, time O(nlogm)
776+
2. 从右上角开始比较,if (target > matrix[row][col]) row++; else col--;
777+
778+
~~~
779+
public class Solution {
780+
public boolean searchMatrix(int[][] matrix, int target) {
781+
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;
782+
int h = matrix.length;
783+
int w = matrix[0].length;
784+
785+
int row = 0;
786+
int col = w - 1;
787+
while (row < h && col >= 0) {
788+
if (target == matrix[row][col]) return true;
789+
else if (target > matrix[row][col]) {
790+
row++;
791+
}
792+
else {
793+
col--;
794+
}
795+
}
796+
return false;
797+
}
798+
}
799+
~~~
800+
801+
## 378. Kth Smallest Element in a Sorted Matrix
802+
Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.
803+
804+
Note that it is the kth smallest element in the sorted order, not the kth distinct element.
805+
806+
Example:
807+
808+
matrix = [
809+
[ 1, 5, 9],
810+
[10, 11, 13],
811+
[12, 13, 15]
812+
],
813+
k = 8,
814+
815+
return 13.
816+
Note:
817+
You may assume k is always valid, 1 ≤ k ≤ n2.
818+
819+
#### Solution
820+
1. 暴力破解,Use max heap maintaining size of K, time O(mnlogk), space O(k), m is matrix height n is matrix width. 完全没有利用到sorted matrix的特点。
821+
2. 类似于 Merge K Sorted Array, 利用了matrix每一个row都sorted的特点,但是没有利用matrix每一个col都sorted的特点, time O(klogm)
822+
3. Binary search, 去左上角为最小值,右下角为最大值,O((m+n)log(max-min)), 在查找每一行最mid小的col的时候可以用二分,则复杂度是O(mlognlog(max-min)), log(max-min)最坏情况下为32.
823+
824+
1 O(mnlogk) 37ms
825+
~~~
826+
public class Solution {
827+
public int kthSmallest(int[][] matrix, int k) {
828+
// if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
829+
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(k, Collections.reverseOrder());
830+
for (int i = 0; i < matrix.length; i++) {
831+
for (int j = 0; j < matrix[0].length; j++) {
832+
if (pq.size() < k) pq.offer(matrix[i][j]);
833+
else if (pq.size() == k && matrix[i][j] < pq.peek()) {
834+
pq.poll();
835+
pq.offer(matrix[i][j]);
836+
}
837+
}
838+
}
839+
return pq.poll();
840+
}
841+
}
842+
~~~
843+
844+
2 28ms
845+
~~~
846+
public class Solution {
847+
class Num {
848+
int value;
849+
int row;
850+
int col;
851+
852+
public Num(int value, int row, int col){
853+
this.value = value;
854+
this.row = row;
855+
this.col = col;
856+
}
857+
}
858+
859+
public int kthSmallest(int[][] matrix, int k) {
860+
PriorityQueue<Num> pq = new PriorityQueue<Num>(new Comparator<Num>() {
861+
public int compare(Num n1, Num n2) {
862+
return n1.value - n2.value;
863+
}
864+
});
865+
866+
int m = matrix.length;
867+
int n = matrix[0].length;
868+
for (int i = 0; i < m; i++) {
869+
pq.offer(new Num(matrix[i][0], i, 0));
870+
}
871+
872+
Num smallest = null;
873+
while (k > 0) {
874+
smallest = pq.poll();
875+
k--;
876+
int row = smallest.row;
877+
int col = smallest.col + 1;
878+
if (col < n) {
879+
Num next = new Num(matrix[row][col], row, col);
880+
pq.offer(next);
881+
}
882+
}
883+
884+
// exception
885+
// if (smallest == null)
886+
887+
return smallest.value;
888+
}
889+
}
890+
~~~
891+
892+
3 1ms
893+
~~~
894+
public class Solution {
895+
public int kthSmallest(int[][] matrix, int k) {
896+
int h = matrix.length;
897+
int w = matrix[0].length;
898+
int low = matrix[0][0];
899+
int high = matrix[h - 1][w - 1];
900+
while (low < high) {
901+
int mid = (high - low) / 2 + low;
902+
int j = w - 1;
903+
int count = 0;
904+
for (int i = 0; i < h; i++) {
905+
while (j >= 0 && matrix[i][j] > mid) j--;
906+
count += j + 1;
907+
}
908+
909+
if (count >= k) {
910+
high = mid;
911+
}
912+
else {
913+
low = mid + 1;
914+
}
915+
}
916+
return low;
917+
}
918+
}
919+
~~~

Array/Sort.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
## 215. Kth Largest Element in an Array
2+
3+
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.
4+
5+
For example,
6+
Given [3,2,1,5,6,4] and k = 2, return 5.
7+
8+
Note:
9+
You may assume k is always valid, 1 ≤ k ≤ array's length.
10+
11+
#### Solution
12+
用Quick Sort来分段,选取pivot元素,一次quick sort后pivot左边的都小于pivot, 右边的都大于pivot, 然后每次丢弃一半的元素
13+
1. average, O(n)
14+
2. worst case O(n^2)
15+
16+
~~~
17+
public class Solution {
18+
public int findKthLargest(int[] nums, int k) {
19+
return quickPartition(nums, 0, nums.length - 1, nums.length - k);
20+
}
21+
22+
public int quickPartition(int[] nums, int start, int end, int k) {
23+
int pivot = end;
24+
int left = start;
25+
26+
for (int i = start; i < end; i++) {
27+
if (nums[i] <= nums[pivot]) {
28+
swap(nums, i, left);
29+
left++;
30+
}
31+
}
32+
swap(nums, left, pivot);
33+
pivot = left;
34+
35+
if (k == pivot) return nums[pivot];
36+
else if (k > pivot) {
37+
quickPartition(nums, pivot + 1, end, k);
38+
}
39+
else {
40+
quickPartition(nums, start, pivot - 1, k);
41+
}
42+
return Integer.MAX_VALUE;
43+
}
44+
45+
private void swap(int[] nums, int i, int j) {
46+
int temp = nums[i];
47+
nums[i] = nums[j];
48+
nums[j] = temp;
49+
}
50+
}
51+
~~~

0 commit comments

Comments
 (0)