其他分享
首页 > 其他分享> > 仓库管理-逆向输入转并查集

仓库管理-逆向输入转并查集

作者:互联网

题目链接meituan-002. 小美的仓库整理 - 力扣(LeetCode)

 

思路,正序每次删除一个节点,将货物多拆出来一堆,反过来看,对于一个空数组,每次向内部插入一个节点,根据节点的位置,使用并查集查找根节点的方式查看是否是连续的。

在插入新节点的时候,最大值只可能被新节点加入到的集合中改变,因此每次加入的时候判断左侧或者右侧是否有值,有的话分别和两侧进行合并,在合并的过程中,修改树的重量即可。

 1 import java.util.*;
 2 class Solution{
 3     // 逆向 并查集
 4     public static void main(String[] args){
 5         Scanner scan = new Scanner(System.in);
 6         int n = scan.nextInt();
 7         int[] w = new int[n];
 8         for(int i=0;i<n;i++){
 9             w[i] = scan.nextInt();
10         }
11         int[] pick = new int[n]; // 当前选择的
12         for(int i=0;i<n;i++){
13             pick[i] = scan.nextInt()-1;
14         }
15         int max = -1;
16         UnionFind uf = new UnionFind(n);
17         int[] ans = new int[n];
18      
19         for(int i=n-1;i>=0;i--){  
20             int pos = pick[i]; // 逆序
21             // 在pos
22             uf.parent[pos] = pos;// 插入后自己指向自己
23             uf.sum[pos] = w[pos];// 插入后以自己为头的重量
24             if(pos>0 && uf.parent[pos-1] != -1){ // 左边还有节点
25                 uf.union(pos,pos-1);
26             }
27             if(pos<n-1 && uf.parent[pos+1] !=-1){ // 右边还有节点
28                 uf.union(pos,pos+1);
29             }
30             max = Math.max(max,uf.sum[uf.find(pos)]); // 新加入的点,可能和某个树组成的最大和
31             ans[i] = max;
32         }
33         for(int i=1;i<n;i++){
34             System.out.println(ans[i]);        
35         }
36         System.out.println(0);        
37     }
38 }
39 
40 class UnionFind{
41     int[] parent;
42     int[] sum;
43     int[] size;
44     public UnionFind(int n){
45         this.size = new int[n];
46         this.sum = new int[n]; // 以i为根节点的重量
47         this.parent = new int[n]; // 父节点
48         for(int i=0;i<n;i++){
49             parent[i] = -1;// 代表当前节点还没有加入
50             sum[i] = 0; // 当前总和为0
51             size[i] = 1;
52         }
53     }
54     //找到当前节点的根节点
55     public int find(int p){
56         while(parent[p] != p){
57             parent[p] = parent[parent[p]];
58             p = parent[p];
59         }
60         return p;
61     }
62     //连接
63     public void union(int p,int q){
64         int rootP = find(p);
65         int rootQ = find(q);
66         if(rootP==rootQ){
67             return;
68         }
69         if(size[rootP]>size[rootQ]){
70             parent[rootQ] = rootP; // 合并根节点
71             size[rootP] += size[rootQ]; // 修改元素数量
72             sum[rootP] += sum[rootQ]; // 修改总和
73          }else{
74              parent[rootP] = rootQ;
75              size[rootQ] += size[rootP];
76              sum[rootQ] += sum[rootP];
77          }
78     }
79 }

 

标签:逆向,仓库,sum,查集,pos,rootP,int,rootQ,节点
来源: https://www.cnblogs.com/jsuxk/p/16437886.html