并查集:Disjoint-set

目录

最长连续序列

被环绕的区域

岛屿数量

除法求值


最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

public int longestConsecutive(int[] num) {
    int res = 0;
    HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int n : num) {
        if (!map.containsKey(n)) {
            int left = (map.containsKey(n - 1)) ? map.get(n - 1) : 0;
            int right = (map.containsKey(n + 1)) ? map.get(n + 1) : 0;
            // sum: length of the sequence n is in
            int sum = left + right + 1;
            map.put(n, sum);
            
            // keep track of the max length 
            res = Math.max(res, sum);
            
            // extend the length to the boundary(s)
            // of the sequence
            // will do nothing if n has no neighbors
            map.put(n - left, sum);
            map.put(n + right, sum);
        }
        else {
            // duplicates
            continue;
        }
    }
    return res;
}

被环绕的区域

给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

class Solution {
    public void bfs(char [][]board,int i,int j)
    {
        // These two arrays are used to traverse four directions of a particular cell.
         int []dx={-1,0,1,0};
         int []dy={0,1,0,-1};
         Queue<ArrayList<Integer>>queue=new LinkedList<>();
        // Add the current cell to queue
         queue.add(new ArrayList<>(Arrays.asList(i,j)));
        // Do BFS until queue is empty
          while(!queue.isEmpty())
           {
                  // Retrieve first position in queue
                  ArrayList<Integer>temp=queue.poll();
                  int curx=(int)temp.get(0);
                  int cury=(int)temp.get(1);
                  // Mark it as '1'
                  board[curx][cury]='1';
                  // Mark four cells which are connected to current cell to '1' if cell has 'O' and push it to queue.
                  for(int i1=0;i1<4;i1++)
                  {
                      if(curx+dx[i1]<board.length && curx+dx[i1]>=0 && cury+dy[i1]<board[0].length && cury+dy[i1]>=0)
                      {
                          
                           if(board[curx+dx[i1]][cury+dy[i1]]=='O'){
                           board[curx+dx[i1]][cury+dy[i1]]='1';
                           queue.add(new ArrayList<>(Arrays.asList(curx+dx[i1],cury+dy[i1])));
                          }
                      }
                  }
                  
           }
    }
    public void solve(char[][] board) {
        
            // Traversing on 1st row
            for(int j=0;j<board[0].length;j++)
            {
                // If we found an 'O' on border, we need to make all its connected 'O's to '1's.
                 if(board[0][j]=='O')
                 {
                   bfs(board,0,j);   
                 }
            }
           // Traversing on last row
            for(int j=0;j<board[0].length;j++)
            {
                // If we found an 'O' on border, we need to make all its connected 'O's to '1's.
                if(board[board.length-1][j]=='O')
                    bfs(board,board.length-1,j);
            } 
           // Traversing on first column
            for(int i=0;i<board.length;i++)
            {
                // If we found an 'O' on border, we need to make all its connected 'O's to '1's.
                if(board[i][0]=='O')
                      bfs(board,i,0);
            }
           // Traversing on last column
            for(int i=0;i<board.length;i++)
            {
                // If we found an 'O' on border, we need to make all its connected 'O's to '1's.
                    if(board[i][board[0].length-1]=='O')
                          bfs(board,i,board[0].length-1);
            }
           // Traverse the grid again and perform step 2
            for(int i=0;i<board.length;i++)
            {
                for(int j=0;j<board[0].length;j++)
                {
                    if(board[i][j]=='O')
                        board[i][j]='X';
                  else  if(board[i][j]=='1')
                        board[i][j]='O';
                }
            }
    }
}

岛屿数量

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

public class Solution {

private int n;
private int m;

public int numIslands(char[][] grid) {
    int count = 0;
    n = grid.length;
    if (n == 0) return 0;
    m = grid[0].length;
    for (int i = 0; i < n; i++){
        for (int j = 0; j < m; j++)
            if (grid[i][j] == '1') {
                DFSMarking(grid, i, j);
                ++count;
            }
    }    
    return count;
}

private void DFSMarking(char[][] grid, int i, int j) {
    if (i < 0 || j < 0 || i >= n || j >= m || grid[i][j] != '1') return;
    grid[i][j] = '0';
    DFSMarking(grid, i + 1, j);
    DFSMarking(grid, i - 1, j);
    DFSMarking(grid, i, j + 1);
    DFSMarking(grid, i, j - 1);
}

除法求值

给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。

另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。

返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0 替代这个答案。

/**
    1. Thoughts
        - check if we have enough info to get the result
        - if yes, calculate; if not, return -1.0
        - Method: union find
            - a/b = 2.0 --> b is the root of a; the distance from a to b is 1/2.0
            - if two nums have the same root, we can get the result; a/b=2.0, b/c=3.0
            index   a   b   c
            root    b   c   c 
            dist    2   3   1
            - if we want to know a/c = ?: a = 2 * b = 2 * 3 * c => a/c = 6.0
    2. Corner case
        - if any input is null, return null
        - no enough info, return -1.0
    3. Steps
        - go through equations to union elements with the same root and update root map and distance map
        - go through each query: check if has the same root; find relative dist
*/
class Solution {
    public double[] calcEquation(String[][] e, double[] values, String[][] q) {
        double[] res = new double[q.length];
        Map<String, String> root = new HashMap<>();
        Map<String, Double> dist = new HashMap<>();
        for (int i = 0; i < e.length; i++) {
            String r1 = find(root, dist, e[i][0]);
            String r2 = find(root, dist, e[i][1]);
            root.put(r1, r2);
            dist.put(r1, dist.get(e[i][1]) * values[i] / dist.get(e[i][0]));
        }
        for (int i = 0; i < q.length; i++) {
            if (!root.containsKey(q[i][0]) || !root.containsKey(q[i][1])) {
                res[i] = -1.0;
                continue;
            }
            String r1 = find(root, dist, q[i][0]);
            String r2 = find(root, dist, q[i][1]);
            if (!r1.equals(r2)) {
                res[i] = -1.0;
                continue;
            }
            res[i] = (double) dist.get(q[i][0]) / dist.get(q[i][1]);
        }
        return res;
    }
    
    private String find(Map<String, String> root, Map<String, Double> dist, String s) {
        if (!root.containsKey(s)) {
            root.put(s, s);
            dist.put(s, 1.0);
            return s;
        }
        if (root.get(s).equals(s)) return s;
        String lastP = root.get(s);
        String p = find(root, dist, lastP);
        root.put(s, p);
        dist.put(s, dist.get(s) * dist.get(lastP));
        return p;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
并查集Disjoint Set)是一种数据结构,用于解决集合的合并和查找问题。在Python中可以使用类来实现并查集。引用展示了一个简单的并查集类的代码实现,其中包括了初始化集合、查找集合、合并集合和判断两个元素是否在同一个集合中的方法。另外,引用和展示了对并查集代码的优化,包括路径压缩和按秩合并等技巧,以提高并查集的效率。 在Python中使用并查集可以解决一些实际问题,如求解岛屿个数、朋友圈等。通过将问题转化为集合的合并和查找操作,可以使用并查集来高效地解决这些问题。 所以,如果你需要在Python中实现并查集,可以参考以上的代码实现和优化方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python 数据结构与算法——并查集](https://blog.csdn.net/itnerd/article/details/103916115)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [并查集Python版](https://blog.csdn.net/XZ2585458279/article/details/127274576)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值