leetcode

原创 2016年08月31日 10:30:19

1.创建一种数据结构,使得如下操作时间复杂度为O1):

boolean insert(int val) 如果插入结果已存在,则返回false,反之为true

boolean remove(int val) 要删除的元素存在,则返回true,反之为false

int getRandom() 返回集合中任意元素。概率为该元素出现的次数/元素数总和。

分析:插入要在O(1)之内,很容易。getRandom想要在O(1)时间内,按照元素出现的频率来作为概率,则必须是将所有元素放置(重复元素重复放置)在一维数组中,才能做到。因此,解决删除问题,才是要点。

考虑如下矩阵:

[10,10,20,20,30,30]

当删除10时,删除了a[1]位置的10,然后将元素末尾a[5]30,填充到a[1]

填充后的矩阵

[10,30,20,20,30]

这样,就可以满足getRandom的需求,也能在O(1)时间内完成。

观察如上操作,发现,需要记录每一个元素的下标,每当删除元素时,将集合末尾的元素,直接移动到删除元素的下标处。考虑到重复元素,下标应该是一个集合,而且,这个集合要不断的根据下标值删除,(上例中,就要删除30的下标集合中为5的下标)。为了使这一步时间复杂度为O(1),则只能使用hash

public class RandomizedCollection {
	private Map<Integer, Set<Integer>> map;
	private ArrayList<Integer> arrayList;

	/** Initialize your data structure here. */
	public RandomizedCollection() {
		map = new HashMap<>();
		arrayList = new ArrayList<>();
	}

	/**
	 * Inserts a value to the collection. Returns true if the collection did not
	 * already contain the specified element.
	 */
	public boolean insert(int val) {
		boolean mark = false;
		if (!map.containsKey(val)) {
			Set<Integer> set = new HashSet<>();
			map.put(val, set);
			mark = true;
		}
		map.get(val).add(arrayList.size());
		arrayList.add(val);
		return mark;
	}

	/**
	 * Removes a value from the collection. Returns true if the collection
	 * contained the specified element.
	 */
	public boolean remove(int val) {
		HashSet<Integer> set = new HashSet<>();
		set.remove(0);
		if (!map.containsKey(val)) {
			return false;
		}

		int indexOfVal = map.get(val).iterator().next();
		map.get(val).remove(indexOfVal);
		if (map.get(val).size() == 0)
			map.remove(val);
		// 如果删除的不是尾部元素
		if (indexOfVal != arrayList.size() - 1) {
			int indexLast = arrayList.size() - 1;
			int elemLast = arrayList.get(indexLast);// 获取最后一个元素

			arrayList.set(indexOfVal, elemLast);// 将该元素填补到被删除元素的空白处。
			map.get(elemLast).remove(indexLast);
			map.get(elemLast).add(indexOfVal);
		}
		arrayList.remove(arrayList.size() - 1);
		return true;
	}

	/** Get a random element from the collection. */
	public int getRandom() {
		return arrayList.get(new Random().nextInt(arrayList.size()));
	}
}


2.小矩形组成大矩形

Given N axis-aligned rectangles where N > 0, determine if they all together form an exact cover of a rectangular region.

Each rectangle is represented as a bottom-left point and a top-right point. For example, a unit square is represented as [1,1,2,2]. (coordinate of bottom-left point is (1, 1) and top-right point is (2, 2)).

分析:最后的大矩形,其最左下角的坐标是矩形集合中的最左下坐标,其右上亦如此。只要获取到这两个坐标,矩阵就唯一确定。大矩形的面积,必然等于所有小矩形的面积。

有一种特殊情况:重合的面积正好补齐了残缺的面积。仔细观察大矩形可知,除去四个顶点处的点外,其他小矩形的点都有偶数个。将每个小矩形的四个点放入set集合中,每当遇到重复的则删除,最后剩下的必然是四个顶点处的点。

	public boolean isRectangleCover(int[][] rectangles) {
		if (null == rectangles || 0 > rectangles.length || 4 != rectangles[0].length) {
			return false;
		}
		int xLeft = Integer.MAX_VALUE;
		int yLeft = Integer.MAX_VALUE;

		int xRight = Integer.MIN_VALUE;
		int yRight = Integer.MIN_VALUE;

		int areaSum = 0;
		Set<String> set = new HashSet<>();
		for (int i = 0; i < rectangles.length; i++) {
			xLeft = Math.min(xLeft, rectangles[i][0]);
			yLeft = Math.min(yLeft, rectangles[i][1]);

			xRight = Math.max(xRight, rectangles[i][2]);
			yRight = Math.max(yRight, rectangles[i][3]);

			areaSum += (rectangles[i][2] - rectangles[i][0]) * (rectangles[i][3] - rectangles[i][1]);

			// 将四个点添加到set集合中
			addPoint(rectangles[i][0] + "" + rectangles[i][1], set);
			addPoint(rectangles[i][0] + "" + rectangles[i][3], set);
			addPoint(rectangles[i][2] + "" + rectangles[i][1], set);
			addPoint(rectangles[i][2] + "" + rectangles[i][3], set);
		}

		int newArea = (xRight - xLeft) * (yRight - yLeft);
		if (newArea != areaSum) {
			return false;
		} else {
			if (set.size() == 4 && set.contains(xLeft + "" + yLeft) && set.contains(xLeft + "" + yRight)
					&& set.contains(xRight + "" + yLeft) && set.contains(xRight + "" + yRight)) {
				return true;
			} else {
				return false;
			}
		}
	}

	private void addPoint(String key, Set<String> set) {
		if (set.contains(key)) {
			set.remove(key);
		} else {
			set.add(key);
		}
	}




版权声明: 举报

相关文章推荐

LeetCode2: Median of Two sorted array.

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...

LeetCode5:Longest Palindromic Substring

Given a string S, find the longest palindromic substring in S. You may assume that the maximum l...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

Leetcode8:atoi()

Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cas...

LeetCode3:Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters. For example, ...

LeetCode4: Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in rever...

LeetCode17: 4Sum

Given an array S of n integers, are there elements a, b, c, and d in S such that a&#...

leetcode 19 和leetcode 83

19. Remove Nth Node From End of List 问题描述:Given a linked list, remove the nth node from the end o...

[LeetCode]Next Permutation java leetcode

问题可以被理解为,给定一个整形数组,返回这个数组的下一个字典序。然后问题重点就是字典序是什么,下面是字典序介绍: 【字典序法】 C++的STL库里面有nextPermutation()方法,其实现...

Leetcode note--Leetcode 70climbing Stairs

70. Climbing Stairs  My Submissions Total Accepted: 143040Total Submissions: 37227...

leetcode

水平有限,c语言下的leetcode解答总结,很弱智的说一句,我就做了链表 1:addTwoNumbers: 考察内容: 1:基本指针使用 2:双重指针的使用 ...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)