forked from mJackie/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
278 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package code; | ||
|
||
import java.util.*; | ||
/* | ||
* 218. The Skyline Problem | ||
* 题意:高楼轮廓 | ||
* 难度:Hard | ||
* 分类:Divide and Conquer, Heap, Binary indexed Tree, Segment Tree | ||
* 思路:转化为坐标,按x排序。左端点add,右端点remove,用优先队列输出y坐标,如果y更改了就输出。 | ||
* Tips: | ||
*/ | ||
public class lc218 { | ||
public static void main(String[] args) { | ||
int[][] buildings = {{0,2,3}, {2,5,3}}; | ||
getSkyline(buildings); | ||
} | ||
public static List<int[]> getSkyline(int[][] buildings) { | ||
List<int[]> res = new ArrayList<>(); | ||
int[][] arr = new int[buildings.length*2][2]; | ||
for (int i = 0, j=0; i < buildings.length ; i++) { //转换成坐标 | ||
arr[j][0] = buildings[i][0]; | ||
arr[j][1] = buildings[i][2]; | ||
j++; | ||
arr[j][0] = buildings[i][1]; | ||
arr[j][1] = -buildings[i][2]; //结束节点y用负数表示 | ||
j++; | ||
} | ||
Arrays.sort(arr, new Comparator<int[]>() { //定义比较方法 | ||
@Override | ||
public int compare(int[] o1, int[] o2) { | ||
if(o1[0]!=o2[0]) | ||
return o1[0] - o2[0]; | ||
else | ||
return o2[1] - o1[1]; //注意这一点,防止 {{0,2,3}, {2,5,3}} case。 两个点重合了不会连续输出。 | ||
} | ||
}); | ||
PriorityQueue<Integer> pr = new PriorityQueue<Integer>(); | ||
pr.add(0); | ||
int pre = 0; | ||
for (int i = 0; i < arr.length ; i++) { | ||
if(arr[i][1]>0){ | ||
pr.add(-arr[i][1]); | ||
}else{ | ||
pr.remove(arr[i][1]); | ||
} | ||
if(pr.peek()!=pre){ | ||
res.add(new int[]{arr[i][0], -pr.peek()}); | ||
pre = pr.peek(); | ||
} | ||
} | ||
return res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package code; | ||
|
||
import java.util.Stack; | ||
|
||
/* | ||
* 227. Basic Calculator II | ||
* 题意:表达式计算 | ||
* 难度:Medium | ||
* 分类:String | ||
* 思路:很巧妙的方法,每次遍历到下一个符号的时候,计算前一个符号的运算,泥面膜了复杂的逻辑。 | ||
* + - 运算直接入栈,* / 运算则计算后将结果入栈,实现了 * / 优先运算 | ||
* Tips:自己想的方法会非常麻烦。这个解法非常聪明。 | ||
*/ | ||
public class lc227 { | ||
public int calculate(String s) { | ||
char[] chs = s.replace(" ","").toCharArray(); | ||
int num = 0; | ||
char sign = '+'; | ||
Stack<Integer> st = new Stack(); | ||
for (int i = 0; i < chs.length ; i++) { | ||
if(Character.isDigit(chs[i])){ | ||
num = num * 10 + chs[i]-'0'; | ||
} | ||
if( !Character.isDigit(chs[i]) || i==chs.length-1 ){ //便利到最后,即使不是符号,也要计算 | ||
if(sign=='+'){ | ||
st.push(num); | ||
} | ||
else if(sign=='-'){ | ||
st.push(-num); | ||
} | ||
else if(sign=='*'){ | ||
st.push(st.pop()*num); | ||
} | ||
else if(sign=='/'){ | ||
st.push(st.pop()/num); | ||
} | ||
num = 0; | ||
sign = chs[i]; //非常聪明 | ||
} | ||
} | ||
int res = 0; | ||
for(Integer i : st){ | ||
System.out.println(i); | ||
res += i; | ||
} | ||
return res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package code; | ||
|
||
import java.util.Stack; | ||
|
||
/* | ||
* 230. Kth Smallest Element in a BST | ||
* 题意:二叉搜索树种第k小的数 | ||
* 难度:Medium | ||
* 分类:Binary Search, Tree | ||
* 思路:每次找到最小的值,k--。中序遍历。 | ||
* Tips:非递归中序遍历还是不熟练。。。 | ||
*/ | ||
public class lc230 { | ||
public class TreeNode { | ||
int val; | ||
TreeNode left; | ||
TreeNode right; | ||
|
||
TreeNode(int x) { | ||
val = x; | ||
} | ||
} | ||
public int kthSmallest(TreeNode root, int k) { | ||
Stack<TreeNode> st = new Stack(); | ||
while(!st.isEmpty()||root!=null){ | ||
while(root!=null) { | ||
st.add(root); | ||
root = root.left; | ||
} | ||
root = st.pop(); | ||
k--; | ||
if(k==0) return root.val; | ||
root = root.right; | ||
} | ||
return 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package code; | ||
/* | ||
* 289. Game of Life | ||
* 题意:按照游戏规则,计算下一个时刻的矩阵,inpalce | ||
* 难度:Medium | ||
* 分类:Array | ||
* 思路:和lc130的trick很类似,先替换为其他值,最后再置回 | ||
* 需要注意几点,用2-bit表示状态转移,用&和位移操作省时 | ||
* 需要更新下规则与现在的表示一致 | ||
* Tips: | ||
*/ | ||
public class lc289 { | ||
public void gameOfLife(int[][] board) { | ||
if (board == null || board.length == 0) return; | ||
int m = board.length, n = board[0].length; | ||
|
||
for (int i = 0; i < m; i++) { | ||
for (int j = 0; j < n; j++) { | ||
int lives = liveNeighbors(board, m, n, i, j); | ||
|
||
// In the beginning, every 2nd bit is 0; | ||
// So we only need to care about when will the 2nd bit become 1. | ||
if (board[i][j] == 1 && lives >= 2 && lives <= 3) { | ||
board[i][j] = 3; // Make the 2nd bit 1: 01 ---> 11 | ||
} | ||
if (board[i][j] == 0 && lives == 3) { | ||
board[i][j] = 2; // Make the 2nd bit 1: 00 ---> 10 | ||
} | ||
} | ||
} | ||
|
||
for (int i = 0; i < m; i++) { | ||
for (int j = 0; j < n; j++) { | ||
board[i][j] >>= 1; // Get the 2nd state. | ||
} | ||
} | ||
} | ||
|
||
public int liveNeighbors(int[][] board, int m, int n, int i, int j) { | ||
int lives = 0; | ||
for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, m - 1); x++) { // 用max,min判断边界 | ||
for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, n - 1); y++) { | ||
lives += board[x][y] & 1; | ||
} | ||
} | ||
lives -= board[i][j] & 1; //减去自己 | ||
return lives; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package code; | ||
|
||
import java.util.PriorityQueue; | ||
|
||
public class lc295 { | ||
class MedianFinder { | ||
PriorityQueue<Integer> pq1; //默认是最小,右半边 | ||
PriorityQueue<Integer> pq2; //左半边 | ||
|
||
/** initialize your data structure here. */ | ||
public MedianFinder() { | ||
this.pq1 = new PriorityQueue(); | ||
this.pq2 = new PriorityQueue(); | ||
} | ||
|
||
public void addNum(int num) { | ||
pq1.add(num); //两个队列都过一遍 | ||
pq2.add(-pq1.poll()); | ||
if (pq1.size() < pq2.size()) //如果中位数是一个数,就存在左半边 | ||
pq1.add(-pq2.poll()); | ||
} | ||
|
||
public double findMedian() { | ||
if(pq1.size()==pq2.size()+1) return pq1.peek(); | ||
return -((double)(-pq1.peek()+pq2.peek()))/2; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package code; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
/* | ||
* 315. Count of Smaller Numbers After Self | ||
* 题意:给一个数组,计算这个数右边比这个数小的数的个数 | ||
* 难度:Hard | ||
* 分类:Divide and Conquer, Binary indexed Tree, Segment Tree, Binary Search Tree | ||
* 思路:两种思路,一种用二叉搜索树这类数据结构 https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76580/9ms-short-Java-BST-solution-get-answer-when-building-BST | ||
* 一种归并排序的思路,归并的时候统计左右交换数目。如果一个数从这个数的右边交换到左边,则+1。因为有重复数字,所以用将ndex进行排序 | ||
* https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76583/11ms-JAVA-solution-using-merge-sort-with-explanation | ||
* 再有一种复杂度稍微高点的思路,从后往前插入排序,插入的时候二分搜索 | ||
* https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76576/My-simple-AC-Java-Binary-Search-code | ||
* Tips:好难呀,我日! | ||
*/ | ||
public class lc315 { | ||
class TreeNode{ | ||
int val; | ||
int dup_num; | ||
int sum; | ||
TreeNode left; | ||
TreeNode right; | ||
TreeNode(int val, int dup_num, int sum){ | ||
this.val = val; | ||
this.dup_num = dup_num; //相同点的数目 | ||
this.sum = sum; //该节点左下节点个数,也就是比该节点值小的 | ||
} | ||
} | ||
|
||
TreeNode root; | ||
public List<Integer> countSmaller(int[] nums) { | ||
if(nums.length<1) return new ArrayList<>(); | ||
Integer[] res_arr = new Integer[nums.length]; //用res_arr保存结果,否则结束了还要遍历数来找结果 | ||
root = new TreeNode(nums[nums.length-1], 1, 0); | ||
res_arr[nums.length-1] = 0; | ||
for (int i = nums.length-2; i >=0 ; i--) { | ||
insert(root, nums[i], res_arr, i, 0); | ||
} | ||
return Arrays.asList(res_arr); //数组转换为list | ||
} | ||
|
||
public TreeNode insert(TreeNode tn, int n, Integer[] res_arr, int i, int path){ //path记录了路径上比该点小的节点的个数 | ||
if(tn==null) { | ||
tn = new TreeNode(n, 1, 0); | ||
res_arr[i] = path; | ||
System.out.print(i); | ||
System.out.println("----"+path); | ||
} | ||
else if(tn.val==n){ | ||
tn.dup_num++; | ||
res_arr[i] = path + tn.sum; | ||
}else if(tn.val>n){ | ||
tn.sum++; | ||
tn.left = insert(tn.left, n, res_arr, i, path); | ||
}else{ | ||
tn.right = insert(tn.right, n, res_arr, i, path + tn.dup_num + tn.sum); | ||
} | ||
return tn; //递归,返回的结果为节点,供上层节点赋值 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters