Bläddra i källkod

#feat:leetcode p2286题题解

yangyi 2 veckor sedan
förälder
incheckning
e0d6e68904
2 ändrade filer med 245 tillägg och 0 borttagningar
  1. 206 0
      src/leetcode/p2286/BookMyShow.java
  2. 39 0
      src/leetcode/p2286/BookMyShowTest.java

+ 206 - 0
src/leetcode/p2286/BookMyShow.java

@@ -0,0 +1,206 @@
+package leetcode.p2286;
+
+/**
+ * @ProjectName: LeetCode
+ * @FileName: BookMyShow
+ * @Author: 杨逸
+ * @Data:2024/10/17 9:14
+ * @Description: https://leetcode.cn/problems/booking-concert-tickets-in-groups/
+ * 2286. 以组为单位订音乐会的门票
+ */
+public class BookMyShow {
+    private int n,m;
+    private SegmentTree segmentTree;
+
+    public BookMyShow(int n, int m) {
+        this.n = n;
+        this.m = m;
+        segmentTree = new SegmentTree(n);
+    }
+
+    public int[] gather(int k, int maxRow) {
+        int index = segmentTree.index(0, 0, n - 1,  maxRow, m - k);
+        //没有满足条件的直接返回
+        if (index<0)return new int[]{};
+
+        long seats = segmentTree.querySum(0, 0, n - 1, index, index);
+        segmentTree.update(0,0,n-1,index,k);
+        return new int[]{index,(int)seats};
+    }
+
+    public boolean scatter(int k, long maxRow) {
+        //前maxRow排剩余的座位
+        long leftSeats = (maxRow+1)*m - segmentTree.querySum(0,0,n-1,0,(int)maxRow);
+        if (leftSeats<k)return false;
+        //找到有空座位的排
+        int index = segmentTree.index(0, 0, n - 1, (int)maxRow, m - 1);
+        while (true){
+            //这排有多少空座位
+            leftSeats = m - segmentTree.querySum(0,0,n-1,index,index);
+            if (leftSeats>=k){
+                //这排座位能坐完人
+                segmentTree.update(0,0,n-1,index,k);
+                return true;
+            }
+            //坐一部分人
+            segmentTree.update(0,0,n-1,index,(int)leftSeats);
+            k -= leftSeats;
+            index++;
+        }
+
+    }
+}
+
+class SegmentTree{
+    private long[] tree;
+    private long[] min;
+
+    public SegmentTree(long[] array){
+        int size = getSize(array.length);
+        this.tree = new long[size];
+        this.min = new long[size];
+        tree[0] = build(0, array.length-1, array,0);
+
+    }
+    public SegmentTree(int n){
+        int size = getSize(n);
+        this.tree = new long[size];
+        this.min = new long[size];
+    }
+
+    /**
+     * 构建线段树
+     * @param left
+     * @param right
+     * @param data
+     * @param index
+     * @return long
+     * @description:
+     * @author: 杨逸
+     * @data:2024/10/17 11:32:17
+     * @since 1.0.0
+     */
+    private long build(int left,int right,long[] data,int index){
+        if (left==right){
+            tree[index] = data[left];
+            return data[left];
+        }
+        //取中间索引
+        int middle = (left+right) >> 1;
+        //构建左子树
+        long leftValue = build(left, middle,data,2*index+1);
+        tree[2*index+1] = leftValue;
+        //构建右子树
+        long rightValue = build(middle+1, right,data,2*index+2);
+        tree[2*index+2] = rightValue;
+        tree[index] = leftValue + rightValue;
+        return leftValue + rightValue;
+    }
+
+
+    /**
+     * 更新元素
+     * @param idx 线段树的坐标
+     * @param l 区间的左边界
+     * @param r 区间的右边界
+     * @param index 要更新的位置
+     * @param value 更新的值
+     * @description:
+     * @author: 杨逸
+     * @data:2024/10/18 09:29:00
+     * @since 1.0.0
+     */
+    public void update(int idx, int l, int r, int index, int value){
+        if (l==r){
+            tree[idx] += value;
+            min[idx] += value;
+            return;
+        }
+
+        int mid = (l+r)>>1;
+
+        if (index<=mid){
+            update(idx*2+1,l,mid,index,value);
+        }else {
+            update(idx*2+2,mid+1,r,index,value);
+        }
+
+        tree[idx] = tree[2*idx+1]+tree[2*idx+2];
+        min[idx] = Math.min(min[2*idx+1], min[2*idx+2]);
+    }
+
+    /**
+     * 区间查询
+     * @param idx 当前线段树的坐标
+     * @param left  当前区间的左边界
+     * @param right 当前区间的右边界
+     * @param L 查询区间的左边界
+     * @param R 查询区间的右边界
+     * @return long
+     * @description:
+     * @author: 杨逸
+     * @data:2024/10/18 09:31:25
+     * @since 1.0.0
+     */
+    public long querySum(int idx,int left,int right,int L,int R){
+        if (L<=left && right<=R){
+            return tree[idx];
+        }
+        int mid = (left+right)>>1;
+        long sum = 0;
+        if (L<=mid){
+            sum += querySum(idx*2+1,left,mid,L,R);
+        }
+        if (R>mid){
+            sum += querySum(idx*2+2,mid+1,right,L,R);
+        }
+        return sum;
+    }
+
+    /**
+     * 找到第一个小于value的索引
+     * @param idx 当前坐标
+     * @param l 当前的左边界
+     * @param r 当前的右边界
+     * @param R 查询的右边界
+     * @param value
+     * @return int
+     * @description:
+     * @author: 杨逸
+     * @data:2024/10/18 11:44:18
+     * @since 1.0.0
+     */
+    public int index(int idx,int l,int r,int R,int value){
+        if (min[idx] > value)return -1;
+        if (l==r)return l;
+
+        int mid = (l+r)>>1;
+        //如果左子树满足条件,则递归左子树
+        if (min[idx*2+1] <= value)return index(idx*2+1,l,mid,R,value);
+        //如果右子树满足条件,则递归右子树
+        if (mid < R)return index(idx*2+2,mid+1,r,R,value);
+        return -1;
+    }
+
+    /**
+     * 计算线段树的大小
+     * @param n
+     * @return int
+     * @description:
+     * @author: 杨逸
+     * @data:2024/10/21 08:51:05
+     * @since 1.0.0
+     */
+    private int getSize(int n){
+        String string = Integer.toString(n, 2).replace('0','1');
+        return Integer.parseInt(string, 2) << 1;
+    }
+
+}
+
+/**
+ * Your BookMyShow object will be instantiated and called as such:
+ * BookMyShow obj = new BookMyShow(n, m);
+ * int[] param_1 = obj.gather(k,maxRow);
+ * boolean param_2 = obj.scatter(k,maxRow);
+ */

+ 39 - 0
src/leetcode/p2286/BookMyShowTest.java

@@ -0,0 +1,39 @@
+package leetcode.p2286;
+
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.PriorityQueue;
+
+/**
+ * @ProjectName: LeetCode
+ * @FileName: BookMyShowTest
+ * @Author: 杨逸
+ * @Data:2024/10/20 11:54
+ * @Description:
+ */
+public class BookMyShowTest {
+    @Test
+    public void test(){
+        int n = 2,m =5;
+        BookMyShow bookMyShow = new BookMyShow(n, m);
+        System.out.println(Arrays.toString(bookMyShow.gather(4, 0)));
+        System.out.println(Arrays.toString(bookMyShow.gather(2, 0)));
+        System.out.println(bookMyShow.scatter(5, 1));
+        System.out.println(bookMyShow.scatter(5, 1));
+
+        System.out.println("=================");
+
+        n = 3;
+        m = 999_999_999;
+        bookMyShow = new BookMyShow(n, m);
+        System.out.println(bookMyShow.scatter(1_000_000_000, 2));
+        System.out.println(Arrays.toString(bookMyShow.gather(999_999_999, 2)));
+        System.out.println(Arrays.toString(bookMyShow.gather(999_999_999, 2)));
+        System.out.println(Arrays.toString(bookMyShow.gather(999_999_999, 2)));
+
+        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
+
+    }
+}