class035 数据结构设计高频题【算法】

class035 数据结构设计高频题【算法】

算法讲解035【必备】数据结构设计高频题

code1 设计有setAll功能的哈希表

// setAll功能的哈希表

// 测试链接 : https://www.nowcoder.com/practice/7c4559f138e74ceb9ba57d76fd169967

// 请同学们务必参考如下代码中关于输入、输出的处理

// 这是输入输出处理效率很高的写法

// 提交以下的code,提交时请把类名改成"Main",可以直接通过

思路:带时间戳

java 复制代码
package class035;

// setAll功能的哈希表
// 测试链接 : https://www.nowcoder.com/practice/7c4559f138e74ceb9ba57d76fd169967
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.HashMap;

public class Code01_SetAllHashMap {

	public static HashMap<Integer, int[]> map = new HashMap<>();
	public static int setAllValue;
	public static int setAllTime;
	public static int cnt;

	public static void put(int k, int v) {
		if (map.containsKey(k)) {
			int[] value = map.get(k);
			value[0] = v;
			value[1] = cnt++;
		} else {
			map.put(k, new int[] { v, cnt++ });
		}
	}

	public static void setAll(int v) {
		setAllValue = v;
		setAllTime = cnt++;
	}

	public static int get(int k) {
		if (!map.containsKey(k)) {
			return -1;
		}
		int[] value = map.get(k);
		if (value[1] > setAllTime) {
			return value[0];
		} else {
			return setAllValue;
		}
	}

	public static int n, op, a, b;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StreamTokenizer in = new StreamTokenizer(br);
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		while (in.nextToken() != StreamTokenizer.TT_EOF) {
			map.clear();
			setAllValue = 0;
			setAllTime = -1;
			cnt = 0;
			n = (int) in.nval;
			for (int i = 0; i < n; i++) {
				in.nextToken();
				op = (int) in.nval;
				if (op == 1) {
					in.nextToken();
					a = (int) in.nval;
					in.nextToken();
					b = (int) in.nval;
					put(a, b);
				} else if (op == 2) {
					in.nextToken();
					a = (int) in.nval;
					out.println(get(a));
				} else {
					in.nextToken();
					a = (int) in.nval;
					setAll(a);
				}
			}
		}
		out.flush();
		out.close();
		br.close();
	}

}

code2 146. LRU 缓存

// 实现LRU结构

// 测试链接 : https://leetcode.cn/problems/lru-cache/

思路:HashMap+双向链表(新增结点到尾部,删除头部的结点,将结点移到尾部)

java 复制代码
package class035;

import java.util.HashMap;

// 实现LRU结构
public class Code02_LRU {

	// 测试链接 : https://leetcode.cn/problems/lru-cache/
	class LRUCache {

		class DoubleNode {
			public int key;
			public int val;
			public DoubleNode last;
			public DoubleNode next;

			public DoubleNode(int k, int v) {
				key = k;
				val = v;
			}
		}

		class DoubleList {
			private DoubleNode head;
			private DoubleNode tail;

			public DoubleList() {
				head = null;
				tail = null;
			}

			public void addNode(DoubleNode newNode) {
				if (newNode == null) {
					return;
				}
				if (head == null) {
					head = newNode;
					tail = newNode;
				} else {
					tail.next = newNode;
					newNode.last = tail;
					tail = newNode;
				}
			}

			public void moveNodeToTail(DoubleNode node) {
				if (tail == node) {
					return;
				}
				if (head == node) {
					head = node.next;
					head.last = null;
				} else {
					node.last.next = node.next;
					node.next.last = node.last;
				}
				node.last = tail;
				node.next = null;
				tail.next = node;
				tail = node;
			}

			public DoubleNode removeHead() {
				if (head == null) {
					return null;
				}
				DoubleNode ans = head;
				if (head == tail) {
					head = null;
					tail = null;
				} else {
					head = ans.next;
					ans.next = null;
					head.last = null;
				}
				return ans;
			}

		}

		private HashMap<Integer, DoubleNode> keyNodeMap;

		private DoubleList nodeList;

		private final int capacity;

		public LRUCache(int cap) {
			keyNodeMap = new HashMap<>();
			nodeList = new DoubleList();
			capacity = cap;
		}

		public int get(int key) {
			if (keyNodeMap.containsKey(key)) {
				DoubleNode ans = keyNodeMap.get(key);
				nodeList.moveNodeToTail(ans);
				return ans.val;
			}
			return -1;
		}

		public void put(int key, int value) {
			if (keyNodeMap.containsKey(key)) {
				DoubleNode node = keyNodeMap.get(key);
				node.val = value;
				nodeList.moveNodeToTail(node);
			} else {
				if (keyNodeMap.size() == capacity) {
					keyNodeMap.remove(nodeList.removeHead().key);
				}
				DoubleNode newNode = new DoubleNode(key, value);
				keyNodeMap.put(key, newNode);
				nodeList.addNode(newNode);
			}
		}

	}

}

code3 380. O(1) 时间插入、删除和获取随机元素

// 插入、删除和获取随机元素O(1)时间的结构

// 测试链接 : https://leetcode.cn/problems/insert-delete-getrandom-o1/

思路:HashMap+动态数组 remove()方法使用最后一个元素填补中间的空缺

java 复制代码
package class035;

import java.util.ArrayList;
import java.util.HashMap;

// 插入、删除和获取随机元素O(1)时间的结构
public class Code03_InsertDeleteRandom {

	// 测试链接 : https://leetcode.cn/problems/insert-delete-getrandom-o1/
	class RandomizedSet {

		public HashMap<Integer, Integer> map;

		public ArrayList<Integer> arr;

		public RandomizedSet() {
			map = new HashMap<>();
			arr = new ArrayList<>();
		}

		public boolean insert(int val) {
			if (map.containsKey(val)) {
				return false;
			}
			map.put(val, arr.size());
			arr.add(val);
			return true;
		}

		public boolean remove(int val) {
			if (!map.containsKey(val)) {
				return false;
			}
			int valIndex = map.get(val);
			int endValue = arr.get(arr.size() - 1);
			map.put(endValue, valIndex);
			arr.set(valIndex, endValue);
			map.remove(val);
			arr.remove(arr.size() - 1);
			return true;
		}

		public int getRandom() {
			return arr.get((int) (Math.random() * arr.size()));
		}

	}

}

code4 381. O(1) 时间插入、删除和获取随机元素 - 允许重复

// 插入、删除和获取随机元素O(1)时间且允许有重复数字的结构

// 测试链接 :

// https://leetcode.cn/problems/insert-delete-getrandom-o1-duplicates-allowed/

思路:HashMap<Integer,HashSet< Integer>>+动态数组 remove()方法使用最后一个元素填补中间的空缺

java 复制代码
package class035;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

// 插入、删除和获取随机元素O(1)时间且允许有重复数字的结构
public class Code04_InsertDeleteRandomDuplicatesAllowed {

	// 测试链接 :
	// https://leetcode.cn/problems/insert-delete-getrandom-o1-duplicates-allowed/
	class RandomizedCollection {

		public HashMap<Integer, HashSet<Integer>> map;

		public ArrayList<Integer> arr;

		public RandomizedCollection() {
			map = new HashMap<>();
			arr = new ArrayList<>();
		}

		public boolean insert(int val) {
			arr.add(val);
			HashSet<Integer> set = map.getOrDefault(val, new HashSet<Integer>());
			set.add(arr.size() - 1);
			map.put(val, set);
			return set.size() == 1;
		}

		public boolean remove(int val) {
			if (!map.containsKey(val)) {
				return false;
			}
			HashSet<Integer> valSet = map.get(val);
			int valAnyIndex = valSet.iterator().next();
			int endValue = arr.get(arr.size() - 1);
			if (val == endValue) {
				valSet.remove(arr.size() - 1);
			} else {
				HashSet<Integer> endValueSet = map.get(endValue);
				endValueSet.add(valAnyIndex);
				arr.set(valAnyIndex, endValue);
				endValueSet.remove(arr.size() - 1);
				valSet.remove(valAnyIndex);
			}
			arr.remove(arr.size() - 1);
			if (valSet.isEmpty()) {
				map.remove(val);
			}
			return true;
		}

		public int getRandom() {
			return arr.get((int) (Math.random() * arr.size()));
		}
	}

}

code5 295. 数据流的中位数

// 快速获得数据流的中位数的结构

// 测试链接 : https://leetcode.cn/problems/find-median-from-data-stream/

思路:大根堆+小根堆

java 复制代码
package class035;

import java.util.PriorityQueue;

// 快速获得数据流的中位数的结构
public class Code05_MedianFinder {

	// 测试链接 : https://leetcode.cn/problems/find-median-from-data-stream/
	class MedianFinder {

		private PriorityQueue<Integer> maxHeap;

		private PriorityQueue<Integer> minHeap;

		public MedianFinder() {
			maxHeap = new PriorityQueue<>((a, b) -> b - a);
			minHeap = new PriorityQueue<>((a, b) -> a - b);
		}

		public void addNum(int num) {
			if (maxHeap.isEmpty() || maxHeap.peek() >= num) {
				maxHeap.add(num);
			} else {
				minHeap.add(num);
			}
			balance();
		}

		public double findMedian() {
			if (maxHeap.size() == minHeap.size()) {
				return (double) (maxHeap.peek() + minHeap.peek()) / 2;
			} else {
				return maxHeap.size() > minHeap.size() ? maxHeap.peek() : minHeap.peek();
			}
		}

		private void balance() {
			if (Math.abs(maxHeap.size() - minHeap.size()) == 2) {
				if (maxHeap.size() > minHeap.size()) {
					minHeap.add(maxHeap.poll());
				} else {
					maxHeap.add(minHeap.poll());
				}
			}
		}

	}

}

code6 895. 最大频率栈

// 最大频率栈

// 测试链接 : https://leetcode.cn/problems/maximum-frequency-stack/

思路:多级链表+HashMap

java 复制代码
package class035;

import java.util.ArrayList;
import java.util.HashMap;

// 最大频率栈
public class Code06_MaximumFrequencyStack {

	// 测试链接 : https://leetcode.cn/problems/maximum-frequency-stack/
	class FreqStack {

		// 出现的最大次数
		private int topTimes;
		// 每层节点
		private HashMap<Integer, ArrayList<Integer>> cntValues = new HashMap<>();
		// 每一个数出现了几次
		private HashMap<Integer, Integer> valueTimes = new HashMap<>();

		public void push(int val) {
			valueTimes.put(val, valueTimes.getOrDefault(val, 0) + 1);
			int curTopTimes = valueTimes.get(val);
			if (!cntValues.containsKey(curTopTimes)) {
				cntValues.put(curTopTimes, new ArrayList<>());
			}
			ArrayList<Integer> curTimeValues = cntValues.get(curTopTimes);
			curTimeValues.add(val);
			topTimes = Math.max(topTimes, curTopTimes);
		}

		public int pop() {
			ArrayList<Integer> topTimeValues = cntValues.get(topTimes);
			int ans = topTimeValues.remove(topTimeValues.size() - 1);
			if (topTimeValues.size() == 0) {
				cntValues.remove(topTimes--);
			}
			int times = valueTimes.get(ans);
			if (times == 1) {
				valueTimes.remove(ans);
			} else {
				valueTimes.put(ans, times - 1);
			}
			return ans;
		}
	}

}

code7 432. 全 O(1) 的数据结构

// 全O(1)的数据结构

// 测试链接 : https://leetcode.cn/problems/all-oone-data-structure/

思路:HashMap+双向链表

java 复制代码
package class035;

import java.util.HashMap;
import java.util.HashSet;

// 全O(1)的数据结构
public class Code07_AllO1 {

	// 测试链接 : https://leetcode.cn/problems/all-oone-data-structure/
	class AllOne {

		class Bucket {
			public HashSet<String> set;
			public int cnt;
			public Bucket last;
			public Bucket next;

			public Bucket(String s, int c) {
				set = new HashSet<>();
				set.add(s);
				cnt = c;
			}
		}

		private void insert(Bucket cur, Bucket pos) {
			cur.next.last = pos;
			pos.next = cur.next;
			cur.next = pos;
			pos.last = cur;
		}

		private void remove(Bucket cur) {
			cur.last.next = cur.next;
			cur.next.last = cur.last;
		}

		Bucket head;

		Bucket tail;

		HashMap<String, Bucket> map;

		public AllOne() {
			head = new Bucket("", 0);
			tail = new Bucket("", Integer.MAX_VALUE);
			head.next = tail;
			tail.last = head;
			map = new HashMap<>();
		}

		public void inc(String key) {
			if (!map.containsKey(key)) {
				if (head.next.cnt == 1) {
					map.put(key, head.next);
					head.next.set.add(key);
				} else {
					Bucket newBucket = new Bucket(key, 1);
					map.put(key, newBucket);
					insert(head, newBucket);
				}
			} else {
				Bucket bucket = map.get(key);
				if (bucket.next.cnt == bucket.cnt + 1) {
					map.put(key, bucket.next);
					bucket.next.set.add(key);
				} else {
					Bucket newBucket = new Bucket(key, bucket.cnt + 1);
					map.put(key, newBucket);
					insert(bucket, newBucket);
				}
				bucket.set.remove(key);
				if (bucket.set.isEmpty()) {
					remove(bucket);
				}
			}
		}

		public void dec(String key) {
			Bucket bucket = map.get(key);
			if (bucket.cnt == 1) {
				map.remove(key);
			} else {
				if (bucket.last.cnt == bucket.cnt - 1) {
					map.put(key, bucket.last);
					bucket.last.set.add(key);
				} else {
					Bucket newBucket = new Bucket(key, bucket.cnt - 1);
					map.put(key, newBucket);
					insert(bucket.last, newBucket);
				}
			}
			bucket.set.remove(key);
			if (bucket.set.isEmpty()) {
				remove(bucket);
			}
		}

		public String getMaxKey() {
			return tail.last.set.iterator().next();
		}

		public String getMinKey() {
			return head.next.set.iterator().next();
		}

	}

}
相关推荐
神经美学_茂森37 分钟前
【通俗理解】神经网络中步长缩小的奥秘:优化算法与卷积操作的影响
网络·神经网络·算法
jay丿2 小时前
正则表达式
服务器·mysql·算法·正则表达式·php
kitesxian3 小时前
Leetcode53. 最大子数组和(HOT100)
数据结构·算法·leetcode
重生之我在VS写bug5 小时前
【C++知识总结2】C++里面的小配角cout和cin
数据结构·c++·算法
HUT_Tyne2655 小时前
力扣--LCR 141.训练计划III
算法·leetcode·职场和发展
pzn25066 小时前
蓝桥杯练习题
c++·算法·蓝桥杯
奶茶戒断高手7 小时前
【CSP CCF记录】201903-2第16次认证 二十四点
数据结构·c++·算法
xxxmmc7 小时前
Leetcode 290 word Pattern
算法·leetcode·hashmap双映射
羽墨灵丘8 小时前
0-1背包问题(1):贪心算法
算法·贪心算法
shepherd枸杞泡茶8 小时前
C# 数据结构之【队列】C#队列
开发语言·数据结构·c#