提交 6e70e3a7 编写于 作者: L liu13

20190227

上级 47e88aac
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
}
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; //递归,返回的结果为节点,供上层节点赋值
}
}
......@@ -135,6 +135,7 @@ Language: Java
| 301 [Java](./code/lc301.java)
| 309 [Java](./code/lc309.java)
| 312 [Java](./code/lc312.java)
| 322 [Java](./code/lc322.java)
| 337 [Java](./code/lc337.java)
| 338 [Java](./code/lc338.java)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册