dengxinyi 6 anos atrás
pai
commit
15dd28e388

+ 20 - 5
medium/355.design-twitter.go

@@ -9,14 +9,14 @@ type tweet struct {
 	ts int
 }
 
-type tweetPQ []tweet
+type tweetPQ []*list.Element
 
 func (pq tweetPQ) Len() int           { return len(pq) }
-func (pq tweetPQ) Less(i, j int) bool { return pq[j].ts < pq[i].ts }
+func (pq tweetPQ) Less(i, j int) bool { return pq[j].Value.(tweet).ts < pq[i].Value.(tweet).ts }
 func (pq tweetPQ) Swap(i, j int)      { pq[i], pq[j] = pq[j], pq[i] }
 
 func (pq *tweetPQ) Push(x interface{}) {
-	*pq = append(*pq, x.(tweet))
+	*pq = append(*pq, x.(*list.Element))
 }
 
 func (pq *tweetPQ) Pop() interface{} {
@@ -27,6 +27,7 @@ func (pq *tweetPQ) Pop() interface{} {
 
 /** Initialize your data structure here. */
 func Constructor() (twitter Twitter) {
+	twitter.tweets = make(map[int]*list.List)
 	twitter.follow = make(map[int]map[int]bool)
 	return
 }
@@ -36,6 +37,9 @@ func (this *Twitter) PostTweet(userId int, tweetId int) {
 	if li, ok := this.tweets[userId]; ok {
 		li.PushFront(tweet{tweetId, this.ts})
 	} else {
+		if _, ok := this.follow[userId]; !ok {
+			this.follow[userId] = map[int]bool{userId: true}
+		}
 		li = list.New()
 		li.PushFront(tweet{tweetId, this.ts})
 		this.tweets[userId] = li
@@ -50,7 +54,18 @@ func (this *Twitter) GetNewsFeed(userId int) []int {
 		var pq tweetPQ
 		for uid, _ := range user {
 			if li, ok := this.tweets[uid]; ok {
-				heap.Push(&pq, li.Front().Value.(tweet))
+				heap.Push(&pq, li.Front())
+			}
+		}
+		for pq.Len() != 0 {
+			t := heap.Pop(&pq).(*list.Element)
+			feed = append(feed, t.Value.(tweet).id)
+			if len(feed) == 10 {
+				return feed
+			}
+			t = t.Next()
+			if t != nil {
+				heap.Push(&pq, t)
 			}
 		}
 	}
@@ -68,7 +83,7 @@ func (this *Twitter) Follow(followerId int, followeeId int) {
 
 /** Follower unfollows a followee. If the operation is invalid, it should be a no-op. */
 func (this *Twitter) Unfollow(followerId int, followeeId int) {
-	if user, ok := this.follow[followerId]; ok {
+	if user, ok := this.follow[followerId]; ok && followerId != followeeId {
 		delete(user, followeeId)
 	}
 }

+ 12 - 0
medium/357.count-numbers-with-unique-digits.go

@@ -0,0 +1,12 @@
+func countNumbersWithUniqueDigits(n int) int {
+	// [0, 10^n)
+	//  0    1    2    3
+	//  1   10   91  739  ...
+	cnt := 1
+	for i, m, j := 1, 0, 0; i <= n && i <= 10; i, cnt = i+1, cnt+m {
+		for m, j = 9, 1; j < i; j++ {
+			m *= 10 - j
+		}
+	}
+	return cnt
+}

+ 31 - 0
medium/368.largest-divisible-subset.go

@@ -0,0 +1,31 @@
+func largestDivisibleSubset(nums []int) (res []int) {
+	n := len(nums)
+	if n <= 1 {
+		return nums
+	}
+	sort.Sort(sort.Reverse(sort.IntSlice(nums)))
+	dp, adj := make([]int, n), make([]int, n)
+	for i := 0; i < n; i++ {
+		dp[i], adj[i] = 1, -1
+	}
+	max, idx := 0, 0
+	for i := 1; i < n; i++ { // DP + math
+		for j := 0; j < i; j++ {
+			if nums[j]%nums[i] != 0 {
+				continue
+			}
+			if dp[i] < dp[j]+1 {
+				dp[i], adj[i] = dp[j]+1, j
+			}
+			if max < dp[i] {
+				max, idx = dp[i], i
+			}
+		}
+	}
+	for adj[idx] != -1 {
+		res = append(res, nums[idx])
+		idx = adj[idx]
+	}
+	return append(res, nums[idx])
+}
+

+ 54 - 0
medium/372.super-pow.go

@@ -0,0 +1,54 @@
+func superPow(a int, b []int) int { // Recurse
+	n := len(b)
+	if n == 0 {
+		return 1
+	}
+	return modPow(superPow(a, b[:n-1]), 10) * modPow(a, b[n-1]) % 1337
+}
+
+func modPow(a, b int) (pow int) {
+	pow, a = 1, a%1337
+	for b != 0 {
+		if b&1 == 1 {
+			pow = pow * a % 1337
+		}
+		b >>= 1
+		a = a * a % 1337
+	}
+	return
+}
+
+func superPowFP(a int, b []int) int { // Fast power
+	pow, n, hi := 1, len(b), 0
+	a %= 1337
+	for !eq0(b, hi) {
+		if b[n-1]&1 == 1 {
+			pow = pow * a % 1337
+		}
+		div2(b, &hi)
+		a = a * a % 1337
+	}
+	return pow
+}
+
+func eq0(bn []int, hi int) bool {
+	for i := len(bn) - 1; hi <= i; i-- {
+		if bn[i] != 0 {
+			return false
+		}
+	}
+	return true
+}
+
+func div2(bn []int, hi *int) {
+	i := *hi
+	if bn[*hi] == 1 {
+		(*hi)++
+	}
+	n := len(bn)
+	for rem := 0; i < n; i++ {
+		num := bn[i] + rem*10
+		bn[i], rem = num>>1, num&1
+	}
+}
+

+ 67 - 0
medium/373.find-k-pairs-with-smallest-sums.go

@@ -0,0 +1,67 @@
+type pair struct {
+	_1 int
+	_2 int
+}
+
+type pairs []pair
+
+func (ps pairs) Len() int           { return len(ps) }
+func (ps pairs) Less(i, j int) bool { return ps[i]._1 < ps[j]._1 }
+func (ps pairs) Swap(i, j int)      { ps[i], ps[j] = ps[j], ps[i] }
+
+func (ps *pairs) Push(x interface{}) {
+	*ps = append(*ps, x.(pair))
+}
+
+func (ps *pairs) Pop() interface{} {
+	x := (*ps)[ps.Len()-1]
+	*ps = (*ps)[:ps.Len()-1]
+	return x
+}
+
+func kSmallestPairs(nums1 []int, nums2 []int, k int) (res [][]int) {
+	m, n := len(nums1), len(nums2)
+	if m == 0 || n == 0 {
+		return
+	}
+	idx := make([]int, m)
+	if m*n < k {
+		k = m * n
+	}
+	var ps pairs = make([]pair, 0)
+	for i := 0; i < m; i++ {
+		heap.Push(&ps, pair{nums1[i] + nums2[0], i})
+	}
+	for i := 0; i < k; i++ {
+		x := heap.Pop(&ps).(pair)
+		res = append(res, []int{nums1[x._2], nums2[idx[x._2]]})
+		idx[x._2]++
+		if idx[x._2] < n {
+			heap.Push(&ps, pair{nums1[x._2] + nums2[idx[x._2]], x._2})
+		}
+	}
+	return
+}
+
+type nx2Arr [][]int
+
+func (arr nx2Arr) Len() int           { return len(arr) }
+func (arr nx2Arr) Less(i, j int) bool { return arr[i][0]+arr[i][1] < arr[j][0]+arr[j][1] }
+func (arr nx2Arr) Swap(i, j int)      { arr[i], arr[j] = arr[j], arr[i] }
+
+func kSmallestPairsBS(nums1 []int, nums2 []int, k int) [][]int { // Brute search
+	m, n := len(nums1), len(nums2)
+	var sorted nx2Arr = make([][]int, m*n)
+	for l, i := 0, 0; i < m; i++ {
+		for j := 0; j < n; j++ {
+			sorted[l] = []int{nums1[i], nums2[j]}
+			l++
+		}
+	}
+	sort.Sort(sorted)
+	if m*n <= k {
+		return sorted
+	}
+	return sorted[:k]
+}
+

+ 34 - 0
medium/375.guess-number-higher-or-lower-ii.go

@@ -0,0 +1,34 @@
+func getMoneyAmount(n int) int {
+	dp := make([][]int, n+1)
+	for i := 1; i <= n; i++ {
+		dp[i] = make([]int, n+1)
+	}
+	return search(dp, 1, n)
+}
+
+func search(dp [][]int, beg, end int) int {
+	if end <= beg {
+		return 0
+	}
+	if dp[beg][end] != 0 {
+		return dp[beg][end]
+	}
+	dp[beg][end] = 1<<32 - 1
+	for i := beg; i <= end; i++ {
+		left := search(dp, beg, i-1)
+		right := search(dp, i+1, end)
+		min := i + maxInt(left, right) // Prepare for the worst, but do your best
+		if min < dp[beg][end] {
+			dp[beg][end] = min
+		}
+	}
+	return dp[beg][end]
+}
+
+func maxInt(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}
+