[算法]并查集(Java版)之矩阵中相邻的元素

  1. 参考博客:并查集算法通俗讲解
  2. 参考博客:可以使用并查集算法解决的算法题

矩阵中相邻的数

题目描述

一个矩阵5*5,矩阵成员如下:

[[1,2,3,4,5],

[11,12,13,14,15],

[21,22,23,24,25],

[31,32,33,34,35],

[41,42,43,44,45]]

输入6个矩阵元素,判断这6个元素是否为一个群组。

输入描述

包含6个矩阵成员的数组,如:1 2 3 4 5 11以一个空格分隔,支持多行

1 2 3 4 5 11

1 2 11 14 25 15

输出描述

满足输出1

不满足输出0

1

0

代码

import java.util.ArrayList;


/**
* 并查集
* @author wall
* @data 2019/8/29 11:04
**/
public class Main2 {
    private static int count;
    private static int index;
    public static void main(String[] args) {
        int [] data = new int[]{1,2,3,4,5,11};
        if (findGroup(data) == 1){
            System.out.println(1);
        }else {
            System.out.println(0);
        }
    }
    private static int findGroup(int [] data){
        int n = data.length;
        count = n;
        int [] id = new int[n];
        int [] sz = new int[n];
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < n ; i ++){
            list.add(data[i]);
            id[i] = i;
            sz[i] = 1;
        }
        //遍历data数组
        for (int i = 0 ; i < n; i ++){
            //判断是否连通
            if (connect(i,list,data)){
                union(i,index,id,sz);
            }else {
                return 0;
            }
        }


        return count;
    }
    private static int find(int i , int [] id){
        //返回父节点
        while (i!=id[i])
            i = id[i];
        return i;
    }
    private static void union(int i ,int j ,int [] id ,int [] sz){
        //i的根节点
        int iRoot = find(i,id);
        //j的根节点
        int jRoot = find(j,id);
        if (iRoot == jRoot)
            return;
        //根据群组中的个数决定将谁合并
        if (sz[iRoot] < sz[jRoot]) {
            id[iRoot] = jRoot;
            sz[jRoot] += sz[iRoot];
        } else {
            id[jRoot] = iRoot;
            sz[iRoot] += sz[jRoot];
        }
        count--;
    }
    //判断节点是否连通
    private static boolean connect(int i ,ArrayList<Integer> list,int [] data){
        //判断list中是否有i的相邻节点
        //左右上下
        int right = data[i] + 1;
        int left = data[i] -1;
        int up = data[i]- 10;
        int down = data[i] + 10;
        if (right>=1&&right<=45&&list.contains(right)){
            index = list.indexOf(right);
            return true;
        }
        if (left>=1&&left<=45&&list.contains(left)){
            index = list.indexOf(left);
            return true;
        }
        if (up>=1&&up<=45&&list.contains(up)){
            index = list.indexOf(up);
            return true;
        }
        if (down>=1&&down<=45&&list.contains(down)){
            index = list.indexOf(down);
            return true;
        }
        return false;
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值