Skip to content

Commit 6e70e3a

Browse files
committed
20190227
1 parent 47e88aa commit 6e70e3a

File tree

7 files changed

+278
-0
lines changed

7 files changed

+278
-0
lines changed

code/lc218.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package code;
2+
3+
import java.util.*;
4+
/*
5+
* 218. The Skyline Problem
6+
* 题意:高楼轮廓
7+
* 难度:Hard
8+
* 分类:Divide and Conquer, Heap, Binary indexed Tree, Segment Tree
9+
* 思路:转化为坐标,按x排序。左端点add,右端点remove,用优先队列输出y坐标,如果y更改了就输出。
10+
* Tips:
11+
*/
12+
public class lc218 {
13+
public static void main(String[] args) {
14+
int[][] buildings = {{0,2,3}, {2,5,3}};
15+
getSkyline(buildings);
16+
}
17+
public static List<int[]> getSkyline(int[][] buildings) {
18+
List<int[]> res = new ArrayList<>();
19+
int[][] arr = new int[buildings.length*2][2];
20+
for (int i = 0, j=0; i < buildings.length ; i++) { //转换成坐标
21+
arr[j][0] = buildings[i][0];
22+
arr[j][1] = buildings[i][2];
23+
j++;
24+
arr[j][0] = buildings[i][1];
25+
arr[j][1] = -buildings[i][2]; //结束节点y用负数表示
26+
j++;
27+
}
28+
Arrays.sort(arr, new Comparator<int[]>() { //定义比较方法
29+
@Override
30+
public int compare(int[] o1, int[] o2) {
31+
if(o1[0]!=o2[0])
32+
return o1[0] - o2[0];
33+
else
34+
return o2[1] - o1[1]; //注意这一点,防止 {{0,2,3}, {2,5,3}} case。 两个点重合了不会连续输出。
35+
}
36+
});
37+
PriorityQueue<Integer> pr = new PriorityQueue<Integer>();
38+
pr.add(0);
39+
int pre = 0;
40+
for (int i = 0; i < arr.length ; i++) {
41+
if(arr[i][1]>0){
42+
pr.add(-arr[i][1]);
43+
}else{
44+
pr.remove(arr[i][1]);
45+
}
46+
if(pr.peek()!=pre){
47+
res.add(new int[]{arr[i][0], -pr.peek()});
48+
pre = pr.peek();
49+
}
50+
}
51+
return res;
52+
}
53+
}

code/lc227.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package code;
2+
3+
import java.util.Stack;
4+
5+
/*
6+
* 227. Basic Calculator II
7+
* 题意:表达式计算
8+
* 难度:Medium
9+
* 分类:String
10+
* 思路:很巧妙的方法,每次遍历到下一个符号的时候,计算前一个符号的运算,泥面膜了复杂的逻辑。
11+
* + - 运算直接入栈,* / 运算则计算后将结果入栈,实现了 * / 优先运算
12+
* Tips:自己想的方法会非常麻烦。这个解法非常聪明。
13+
*/
14+
public class lc227 {
15+
public int calculate(String s) {
16+
char[] chs = s.replace(" ","").toCharArray();
17+
int num = 0;
18+
char sign = '+';
19+
Stack<Integer> st = new Stack();
20+
for (int i = 0; i < chs.length ; i++) {
21+
if(Character.isDigit(chs[i])){
22+
num = num * 10 + chs[i]-'0';
23+
}
24+
if( !Character.isDigit(chs[i]) || i==chs.length-1 ){ //便利到最后,即使不是符号,也要计算
25+
if(sign=='+'){
26+
st.push(num);
27+
}
28+
else if(sign=='-'){
29+
st.push(-num);
30+
}
31+
else if(sign=='*'){
32+
st.push(st.pop()*num);
33+
}
34+
else if(sign=='/'){
35+
st.push(st.pop()/num);
36+
}
37+
num = 0;
38+
sign = chs[i]; //非常聪明
39+
}
40+
}
41+
int res = 0;
42+
for(Integer i : st){
43+
System.out.println(i);
44+
res += i;
45+
}
46+
return res;
47+
}
48+
}

code/lc230.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package code;
2+
3+
import java.util.Stack;
4+
5+
/*
6+
* 230. Kth Smallest Element in a BST
7+
* 题意:二叉搜索树种第k小的数
8+
* 难度:Medium
9+
* 分类:Binary Search, Tree
10+
* 思路:每次找到最小的值,k--。中序遍历。
11+
* Tips:非递归中序遍历还是不熟练。。。
12+
*/
13+
public class lc230 {
14+
public class TreeNode {
15+
int val;
16+
TreeNode left;
17+
TreeNode right;
18+
19+
TreeNode(int x) {
20+
val = x;
21+
}
22+
}
23+
public int kthSmallest(TreeNode root, int k) {
24+
Stack<TreeNode> st = new Stack();
25+
while(!st.isEmpty()||root!=null){
26+
while(root!=null) {
27+
st.add(root);
28+
root = root.left;
29+
}
30+
root = st.pop();
31+
k--;
32+
if(k==0) return root.val;
33+
root = root.right;
34+
}
35+
return 0;
36+
}
37+
}

code/lc289.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package code;
2+
/*
3+
* 289. Game of Life
4+
* 题意:按照游戏规则,计算下一个时刻的矩阵,inpalce
5+
* 难度:Medium
6+
* 分类:Array
7+
* 思路:和lc130的trick很类似,先替换为其他值,最后再置回
8+
* 需要注意几点,用2-bit表示状态转移,用&和位移操作省时
9+
* 需要更新下规则与现在的表示一致
10+
* Tips:
11+
*/
12+
public class lc289 {
13+
public void gameOfLife(int[][] board) {
14+
if (board == null || board.length == 0) return;
15+
int m = board.length, n = board[0].length;
16+
17+
for (int i = 0; i < m; i++) {
18+
for (int j = 0; j < n; j++) {
19+
int lives = liveNeighbors(board, m, n, i, j);
20+
21+
// In the beginning, every 2nd bit is 0;
22+
// So we only need to care about when will the 2nd bit become 1.
23+
if (board[i][j] == 1 && lives >= 2 && lives <= 3) {
24+
board[i][j] = 3; // Make the 2nd bit 1: 01 ---> 11
25+
}
26+
if (board[i][j] == 0 && lives == 3) {
27+
board[i][j] = 2; // Make the 2nd bit 1: 00 ---> 10
28+
}
29+
}
30+
}
31+
32+
for (int i = 0; i < m; i++) {
33+
for (int j = 0; j < n; j++) {
34+
board[i][j] >>= 1; // Get the 2nd state.
35+
}
36+
}
37+
}
38+
39+
public int liveNeighbors(int[][] board, int m, int n, int i, int j) {
40+
int lives = 0;
41+
for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, m - 1); x++) { // 用max,min判断边界
42+
for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, n - 1); y++) {
43+
lives += board[x][y] & 1;
44+
}
45+
}
46+
lives -= board[i][j] & 1; //减去自己
47+
return lives;
48+
}
49+
}

code/lc295.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package code;
2+
3+
import java.util.PriorityQueue;
4+
5+
public class lc295 {
6+
class MedianFinder {
7+
PriorityQueue<Integer> pq1; //默认是最小,右半边
8+
PriorityQueue<Integer> pq2; //左半边
9+
10+
/** initialize your data structure here. */
11+
public MedianFinder() {
12+
this.pq1 = new PriorityQueue();
13+
this.pq2 = new PriorityQueue();
14+
}
15+
16+
public void addNum(int num) {
17+
pq1.add(num); //两个队列都过一遍
18+
pq2.add(-pq1.poll());
19+
if (pq1.size() < pq2.size()) //如果中位数是一个数,就存在左半边
20+
pq1.add(-pq2.poll());
21+
}
22+
23+
public double findMedian() {
24+
if(pq1.size()==pq2.size()+1) return pq1.peek();
25+
return -((double)(-pq1.peek()+pq2.peek()))/2;
26+
}
27+
}
28+
}

code/lc315.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package code;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
/*
7+
* 315. Count of Smaller Numbers After Self
8+
* 题意:给一个数组,计算这个数右边比这个数小的数的个数
9+
* 难度:Hard
10+
* 分类:Divide and Conquer, Binary indexed Tree, Segment Tree, Binary Search Tree
11+
* 思路:两种思路,一种用二叉搜索树这类数据结构 https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76580/9ms-short-Java-BST-solution-get-answer-when-building-BST
12+
* 一种归并排序的思路,归并的时候统计左右交换数目。如果一个数从这个数的右边交换到左边,则+1。因为有重复数字,所以用将ndex进行排序
13+
* https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76583/11ms-JAVA-solution-using-merge-sort-with-explanation
14+
* 再有一种复杂度稍微高点的思路,从后往前插入排序,插入的时候二分搜索
15+
* https://leetcode.com/problems/count-of-smaller-numbers-after-self/discuss/76576/My-simple-AC-Java-Binary-Search-code
16+
* Tips:好难呀,我日!
17+
*/
18+
public class lc315 {
19+
class TreeNode{
20+
int val;
21+
int dup_num;
22+
int sum;
23+
TreeNode left;
24+
TreeNode right;
25+
TreeNode(int val, int dup_num, int sum){
26+
this.val = val;
27+
this.dup_num = dup_num; //相同点的数目
28+
this.sum = sum; //该节点左下节点个数,也就是比该节点值小的
29+
}
30+
}
31+
32+
TreeNode root;
33+
public List<Integer> countSmaller(int[] nums) {
34+
if(nums.length<1) return new ArrayList<>();
35+
Integer[] res_arr = new Integer[nums.length]; //用res_arr保存结果,否则结束了还要遍历数来找结果
36+
root = new TreeNode(nums[nums.length-1], 1, 0);
37+
res_arr[nums.length-1] = 0;
38+
for (int i = nums.length-2; i >=0 ; i--) {
39+
insert(root, nums[i], res_arr, i, 0);
40+
}
41+
return Arrays.asList(res_arr); //数组转换为list
42+
}
43+
44+
public TreeNode insert(TreeNode tn, int n, Integer[] res_arr, int i, int path){ //path记录了路径上比该点小的节点的个数
45+
if(tn==null) {
46+
tn = new TreeNode(n, 1, 0);
47+
res_arr[i] = path;
48+
System.out.print(i);
49+
System.out.println("----"+path);
50+
}
51+
else if(tn.val==n){
52+
tn.dup_num++;
53+
res_arr[i] = path + tn.sum;
54+
}else if(tn.val>n){
55+
tn.sum++;
56+
tn.left = insert(tn.left, n, res_arr, i, path);
57+
}else{
58+
tn.right = insert(tn.right, n, res_arr, i, path + tn.dup_num + tn.sum);
59+
}
60+
return tn; //递归,返回的结果为节点,供上层节点赋值
61+
}
62+
}

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ Language: Java
135135
| 301 [Java](./code/lc301.java)
136136
| 309 [Java](./code/lc309.java)
137137
| 312 [Java](./code/lc312.java)
138+
138139
| 322 [Java](./code/lc322.java)
139140
| 337 [Java](./code/lc337.java)
140141
| 338 [Java](./code/lc338.java)

0 commit comments

Comments
 (0)