leetcode

来源:互联网 发布:mac 如何将lrc嵌入mp3 编辑:程序博客网 时间:2024/04/29 21:16

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);}}




0 0
原创粉丝点击