左云 算法2

6.并查集

1. 判断两个集合是否属于同一集合
2. 合并两个结合

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

首次生成3张map 表

		//包装集合
		public HashMap<V, Node<V>> nodes;
		//记录本集合下所有节点对应的父节点,即谁的父亲是谁
		public HashMap<Node<V>, Node<V>> parents;
		//记录本集合的大小,父亲节点和其下面挂了节点个数。
		//只是父亲节点的时候才会记录到sizeMap中
		public HashMap<Node<V>, Integer> sizeMap;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

查找父亲节点

			Stack<Node<V>> path = new Stack<>();
			//自己指向自己即为代表节点
			//找到代表节点
			while (cur != parents.get(cur)) {
				path.push(cur);
				cur = parents.get(cur);
			}

在这里插入图片描述

在这里插入图片描述

		//合并两个集合
		public void union(V a, V b) {
			Node<V> aHead = findFather(nodes.get(a));
			Node<V> bHead = findFather(nodes.get(b));
			if (aHead != bHead) {
				int aSetSize = sizeMap.get(aHead);
				int bSetSize = sizeMap.get(bHead);
				//大小集合重定向
				Node<V> big = aSetSize >= bSetSize ? aHead : bHead;
				Node<V> small = big == aHead ? bHead : aHead;
				//小集合的代表节点指向大集合的代表节点
				parents.put(small, big);
				sizeMap.put(big, aSetSize + bSetSize);
				//删除小的节点大小
				sizeMap.remove(small);
			}
		}
				//大小集合重定向
				Node<V> big = aSetSize >= bSetSize ? aHead : bHead;
				Node<V> small = big == aHead ? bHead : aHead;
				//小集合的代表节点指向大集合的代表节点
				parents.put(small, big);

在这里插入图片描述

package class14;
package class14;

import java.util.HashMap;
import java.util.List;
import java.util.Stack;

public class Code05_UnionFind {

	public static class Node<V> {
		V value;

		public Node(V v) {
			value = v;
		}
	}

	public static class UnionFind<V> {
		//包装集合
		public HashMap<V, Node<V>> nodes;
		//记录本集合下所有节点对应的父节点,即谁的父亲是谁
		public HashMap<Node<V>, Node<V>> parents;
		//记录本集合的大小,父亲节点和其下面挂了节点个数。
		//只是父亲节点的时候才会记录到sizeMap中
		public HashMap<Node<V>, Integer> sizeMap;

		public UnionFind(List<V> values) {
			nodes = new HashMap<>();
			parents = new HashMap<>();
			sizeMap = new HashMap<>();
			for (V cur : values) {
				Node<V> node = new Node<>(cur);
				nodes.put(cur, node);
				//开始都是自己指向自己
				parents.put(node, node);
				//开始都是都是代表节点,大小为1
				sizeMap.put(node, 1);
			}
		}

		// 给你一个节点,请你往上到不能再往上,把代表返回
		//找到给定节点的代表节点
		public Node<V> findFather(Node<V> cur) {
			Stack<Node<V>> path = new Stack<>();
			//自己指向自己即为代表节点
			//找到代表节点
			while (cur != parents.get(cur)) {
				path.push(cur);
				cur = parents.get(cur);
			}
			//每次返回之前做一次优化,把集合中,中间小的父节点直接指向最上面大的父亲节点,方便下此快速查找
			while (!path.isEmpty()) {
				parents.put(path.pop(), cur);
			}
			return cur;
		}

		//判断是否在一个集合
		//核心判断两个集合代表节点是否相等,相等则是否属于同一个集合
		public boolean isSameSet(V a, V b) {
			return findFather(nodes.get(a)) == findFather(nodes.get(b));
		}

		//合并两个集合
		public void union(V a, V b) {
			Node<V> aHead = findFather(nodes.get(a));
			Node<V> bHead = findFather(nodes.get(b));
			if (aHead != bHead) {
				int aSetSize = sizeMap.get(aHead);
				int bSetSize = sizeMap.get(bHead);
				//大小集合重定向
				Node<V> big = aSetSize >= bSetSize ? aHead : bHead;
				Node<V> small = big == aHead ? bHead : aHead;
				//小集合的代表节点指向大集合的代表节点
				parents.put(small, big);
				sizeMap.put(big, aSetSize + bSetSize);
				//删除小的节点大小
				//合并small不再是父亲节点,要从sizeMap中删掉
				sizeMap.remove(small);
			}
		}

		public int sets() {
			return sizeMap.size();
		}

	}
}

7.贪心算法

局部最优解,是否也是全局最优解
在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值