451. 根据字符出现频率排序 (20221011)
给定字符串 s ,根据字符出现的频率对其进行 降序排序 。频率指的是它出现在字符串中的次数。例:输入: s = “tree”
输出: “eert”
频率遍历排序:(时间复杂度:O(n+klogk),空间复杂度:O(n+k))
func frequencySort(s string) string {
cnt := map[byte]int{}
for i := range s {
cnt[s[i]]++
}
type pair struct {
ch byte
cnt int
}
pairs := make([]pair, 0, len(cnt))
for k,v := range cnt {
pairs = append(pairs, pair{k, v})
}
sort.Slice(pairs, func(i, j int) bool {return pairs[i].cnt > pairs[j].cnt})
ans := make([]byte, 0, len(s))
for _, p := range pairs {
ans = append(ans, bytes.Repeat([]byte{p.ch}, p.cnt)...)
}
return string(ans)
}
``
桶排序(时间复杂度:O(n+k),空间复杂度:O(n+k))
```go
func frequencySort(s string) string {
cnt := map[byte]int{}
maxFreq := 0
for i := range s {
cnt[s[i]]++
maxFreq = max(maxFreq, cnt[s[i]])
}
buckets := make([][]byte, maxFreq + 1)
for ch, c := range cnt {
buckets[c] = append(buckets[c], ch)
}
ans := make([]byte, 0, len(s))
for i:= maxFreq; i >0; i-- {
for _, ch := range buckets {
ans = append(ans, bytes.Repeat([]byte{ch}, i)...)
}
}
}
func max(a, b int) int {
if (a > b) {
return a
}
return b
}
452.用最少数量的箭引爆气球
points = [[10,16],[2,8],[1,6],[7,12]],找出交集最多的一个点。输出x=6,12.
排序+贪心
func findMinArrowShorts(points [][]int) int {
if len(points) == 0 {
return 0
}
sort.Slice(points, func(i, j int){return points[i][1] < points[j][1]})
maxRight := points[0][1]
ans := 1
for _, p := range points {
if p[0] > maxRight {
maxRight = p[1]
ans++
}
}
return ans
}
453. 最小操作次数使数组元素相等
给定一个长度为n的数组,每次操作使n-1个元素加1,返回让所有元素相等的最小操作次数。
换个思维:每次操作使一个元素减1,所有的元素减少到最小元素即可。
func minMoves(nums []int) (ans int) {
min := nums[0]
for _, num := range nums[1:] {
if num < min {
min = num
}
}
for _, num := range nums {
ans += num - min
}
return
}
454. 四数相加
nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]输出下标元组(i,j,k,l)使得nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0的个数。
大事化小,(分组和哈希)a,b为一组
时间复杂度:O(n^2),空间复杂度:O(n^2)
func fourSumCount(a, b, c, d []int) (ans int) {
countAB := map[int]int{}
for _, v := range a {
for _, w := range b {
countAB[v+w]++
}
}
for _, v := range c {
for _, w := range d {
ans += countAB[-v-w]
}
}
return ans
}
455.分发饼干
每个孩子最多只能给一块饼干。孩子的胃量需要小于饼干的尺寸才能满足。孩子满足的最大值?
排序+双指针+贪心(时间复杂度:O(mlogm+nlogn),空间复杂度:O(logm+logn))
func findContentChildren(g []int, s []int) (ans int) {
sort.Ints(g)
sort.Ints(s)
m, n := len(g), len(s)
for i, j := 0, 0; i < m && j < n; i++ {
for j < n && g[i] > s[j] {
j++
}
if j < n {
ans++
j++
}
}
return
}
456.132数组
数组中寻找i < j < k使得 nums[i] < nums[k] < nums[j],成功则返回true 。
枚举1(时间复杂度O(n),空间复杂度O(n))
func find132pattern(nums []int) bool {
n := len(nums)
candidateK := []int{nums[n-1]}
maxK := math.MinInt64
for i := n - 2; i >= 0; i-- {
if nums[i] < maxK {
return true
}
for len(candidateK) > 0 && nums[i] > candidateK[len(candidateK)-1] {
maxK = candidateK[len(candidateK)-1]
candidateK = candidateK[:len(candidateK)-1]
}
if nums[i] > maxK {
candidateK = append(candidateK, nums[i])
}
}
return false
}
贪心算法:是寻找最优解常用方法,将求解过程分成若干个步骤,在每个过程使用贪心算法选取当前状态下最好的选择。