dengxinyi 6 vuotta sitten
vanhempi
commit
c7433935fe

+ 50 - 6
hard/352.data-stream-as-disjoint-intervals.go

@@ -1,12 +1,12 @@
 /**
- * Definition for an interval.
+ * Definition for an inval.
  * type Interval struct {
  *	   Start int
  *	   End   int
  * }
  */
 type SummaryRanges struct {
-	intervals []Interval
+	is []Interval
 }
 
 /** Initialize your data structure here. */
@@ -15,14 +15,58 @@ func Constructor() SummaryRanges {
 }
 
 func (this *SummaryRanges) AddNum(val int) {
-	beg, end := 0, len(this.intervals)
-	for beg < end {
-		
+	n := len(this.is)
+	if n == 0 {
+		this.is = []Interval{{val, val}}
+		return
+	}
+	beg, end := 0, n-1
+	for beg <= end {
+		mid := beg + (end-beg)/2
+		if in := this.is[mid]; in.Start <= val && val <= in.End {
+			return
+		} else if val < in.Start {
+			end = mid - 1
+		} else if in.End < val {
+			beg = mid + 1
+		}
+	}
+	if beg == n {
+		if val == this.is[n-1].End+1 {
+			this.is[n-1].End++
+		} else {
+			this.is = append(this.is, Interval{val, val})
+		}
+	} else if beg == 0 {
+		if val == this.is[0].Start-1 {
+			this.is[0].Start--
+		} else {
+			nis := make([]Interval, n+1)
+			nis[0] = Interval{val, val}
+			copy(nis[1:], this.is)
+			this.is = nis
+		}
+	} else {
+		if l, r := val == this.is[beg-1].End+1, val == this.is[beg].Start-1; l && r {
+			this.is[beg].Start = this.is[beg-1].Start
+			copy(this.is[beg-1:], this.is[beg:])
+			this.is = this.is[:n-1]
+		} else if l {
+			this.is[beg-1].End++
+		} else if r {
+			this.is[beg].Start--
+		} else {
+			nis := make([]Interval, n+1)
+			copy(nis, this.is[:beg])
+			nis[beg] = Interval{val, val}
+			copy(nis[beg+1:], this.is[beg:])
+			this.is = nis // Since append([]T, []T...) is rather inefficient, copy is the best choice
+		}
 	}
 }
 
 func (this *SummaryRanges) GetIntervals() []Interval {
-	
+	return this.is
 }
 
 /**

+ 35 - 0
hard/354.russian-doll-envelopes.go

@@ -0,0 +1,35 @@
+type nx2arr [][]int
+
+func (arr nx2arr) Len() int { return len(arr) }
+func (arr nx2arr) Less(i, j int) bool {
+	if arr[i][0] != arr[j][0] {
+		return arr[i][0] < arr[j][0]
+	} else {
+		return arr[j][1] < arr[i][1] // If the width is the same, the tallest is in front
+	}
+}
+func (arr nx2arr) Swap(i, j int) { arr[i], arr[j] = arr[j], arr[i] }
+
+func maxEnvelopes(envelopes [][]int) (n int) { // Just like "the longest increasing substring"
+	sort.Sort(nx2arr(envelopes))
+	queue := make([][]int, 0)
+	for i := range envelopes {
+		beg, end := 0, n-1
+		for beg <= end {
+			mid := beg + (end-beg)/2
+			if queue[mid][1] < envelopes[i][1] { // Binary search with duplicates
+				beg = mid + 1
+			} else if envelopes[i][1] <= queue[mid][1] {
+				end = mid - 1
+			}
+		}
+		if beg == n {
+			queue = append(queue, envelopes[i])
+			n++
+		} else {
+			queue[beg] = envelopes[i]
+		}
+	}
+	return
+}
+

+ 58 - 0
hard/381.insert-delete-getrandom-o1-duplicates-allowed.go

@@ -0,0 +1,58 @@
+type pair struct {
+	_1 int
+	_2 *list.Element
+}
+
+type RandomizedCollection struct {
+	nums []pair
+	size int
+	pos  map[int]*list.List // Hash map + linked list, O(1) get random, O(1) insert, O(1) remove (average)
+}
+
+/** Initialize your data structure here. */
+func Constructor() RandomizedCollection {
+	return RandomizedCollection{pos: make(map[int]*list.List)}
+}
+
+/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
+func (this *RandomizedCollection) Insert(val int) bool {
+	li, ok := this.pos[val]
+	if !ok {
+		li = list.New()
+		this.pos[val] = li
+	}
+	ele := li.PushBack(this.size)
+	this.nums = append(this.nums, pair{val, ele})
+	this.size++
+	return !ok
+}
+
+/** Removes a value from the collection. Returns true if the collection contained the specified element. */
+func (this *RandomizedCollection) Remove(val int) bool {
+	li, ok := this.pos[val]
+	if !ok {
+		return false
+	}
+	idx := li.Remove(li.Front()).(int)
+	this.size--
+	this.nums[idx] = this.nums[this.size]
+	this.nums[idx]._2.Value = idx
+	this.nums = this.nums[:this.size]
+	if li.Len() == 0 {
+		delete(this.pos, val)
+	}
+	return true
+}
+
+/** Get a random element from the collection. */
+func (this *RandomizedCollection) GetRandom() int {
+	return this.nums[rand.Intn(this.size)]._1
+}
+
+/**
+ * Your RandomizedCollection object will be instantiated and called as such:
+ * obj := Constructor();
+ * param_1 := obj.Insert(val);
+ * param_2 := obj.Remove(val);
+ * param_3 := obj.GetRandom();
+ */