从零开始的力扣刷题记录-第五十天

力扣每日四题

  • 1313. 解压缩编码列表
  • 1518. 换水问题
  • 1700. 无法吃午餐的学生数量
  • 2611. 老鼠和奶酪
  • 总结

1313. 解压缩编码列表

题目描述:
给你一个以行程长度编码压缩的整数列表 nums 。
考虑每对相邻的两个元素 [freq, val] = [nums[2i], nums[2i+1]] (其中 i >= 0 ),每一对都表示解压后子列表中有 freq 个值为 val 的元素,你需要从左到右连接所有子列表以生成解压后的列表。
请你返回解压后的列表。

题解:
直接按描述模拟即可

代码(Go):

func decompressRLElist(nums []int) []int {
    sce := []int{}
    temp := 0
    for i,v := range nums{
        if i%2 == 0{
            temp = v
        }else{
            for i := 0;i < temp;i++{
                sce = append(sce,v)
            }
        }
    }
    return sce
}

1518. 换水问题

题目描述:
超市正在促销,你可以用 numExchange 个空水瓶从超市兑换一瓶水。最开始,你一共购入了 numBottles 瓶水。
如果喝掉了水瓶中的水,那么水瓶就会变成空的。
给你两个整数 numBottles 和 numExchange ,返回你 最多 可以喝到多少瓶水。

题解:
依然是按描述流程模拟,用两个变量分别保存一共喝了多少瓶以及空瓶数量。官方题解有数学方法,直接带公式可以做出来

代码(Go):

func numWaterBottles(numBottles int, numExchange int) int {
    sum := 0
    space := 0
    for numBottles > 0{
        sum += numBottles
        space += numBottles
        numBottles = space/numExchange
        space = space%numExchange
    }
    return sum
}

1700. 无法吃午餐的学生数量

题目描述:
学校的自助午餐提供圆形和方形的三明治,分别用数字 0 和 1 表示。所有学生站在一个队列里,每个学生要么喜欢圆形的要么喜欢方形的。
餐厅里三明治的数量与学生的数量相同。所有三明治都放在一个 栈 里,每一轮:
如果队列最前面的学生 喜欢 栈顶的三明治,那么会 拿走它 并离开队列。
否则,这名学生会 放弃这个三明治 并回到队列的尾部。
这个过程会一直持续到队列里所有学生都不喜欢栈顶的三明治为止。
给你两个整数数组 students 和 sandwiches ,其中 sandwiches[i] 是栈里面第 i​​​​​​ 个三明治的类型(i = 0 是栈的顶部), students[j] 是初始队列里第 j​​​​​​ 名学生对三明治的喜好(j = 0 是队列的最开始位置)。请你返回无法吃午餐的学生数量。

题解:
前面两个题都是模拟给我做出路径依赖了,也是直接模拟做出来的,导致空间占用比较高,官方题解简化了问题,实际上可以直接统计爱吃两种三明治的学生的数量,站位根本不需要考虑,因为队伍无论怎么排只要三明治数量够都能吃到

代码(Go):

func countStudents(students []int, sandwiches []int) int {
    temp := 0
    for len(students) > 0{
        if students[0] == sandwiches[0]{
            students = students[1:]
            sandwiches = sandwiches[1:]
            temp = 0
        }else{
            tempi := students[0]
            students = students[1:]
            students = append(students,tempi)
            temp++
        }
        if temp == len(students){
            break
        }
    }
    return len(students)
}

2611. 老鼠和奶酪

题目描述:
有两只老鼠和 n 块不同类型的奶酪,每块奶酪都只能被其中一只老鼠吃掉。
下标为 i 处的奶酪被吃掉的得分为:
如果第一只老鼠吃掉,则得分为 reward1[i] 。
如果第二只老鼠吃掉,则得分为 reward2[i] 。
给你一个正整数数组 reward1 ,一个正整数数组 reward2 ,和一个非负整数 k 。
请你返回第一只老鼠恰好吃掉 k 块奶酪的情况下,最大 得分为多少。

题解:
核心思路就是先计算两个数组的差值,差值越大说明第一只老鼠吃掉分数更高,以此得到第一只老鼠吃掉的奶酪的范围。最后再遍历数组将得分加起来。官方题解有两处优化,一个是不需要判断第一只老鼠吃掉奶酪的范围,在计算差值数组的时候直接将reward2加起来,再对差值数组排序后加上最大的k个差值即可,第二处优化是由于差分数组只需要取最大的k个值,所以可以用优先队列的方式,减少需要排序的元素个数。

代码(Go):

func miceAndCheese(reward1 []int, reward2 []int, k int) int {
    sce := make([]int,len(reward1))
    for i := 0;i < len(reward1);i++{
        sce[i] = reward1[i] - reward2[i]
    }
    sort.Ints(sce)
    temp := 1000000
    tempk := k
    num := 0
    for i := len(reward1) - 1;i >= 0 && tempk > 0;i--{
        if sce[i] != temp{
            temp = sce[i]
            num = 1
        }else{
            num++
        }
        tempk--
    }
    sum := 0
    for i := 0;i < len(reward1);i++{
        if reward1[i] - reward2[i] > temp{
            sum += reward1[i]
        }else if reward1[i] - reward2[i] < temp{
            sum += reward2[i]
        }else{
            if num > 0{
                sum += reward1[i]
                num--
            }else{
                sum += reward2[i]
            }
        }
    }
    return sum
}

总结

今天的题都有点技巧在的,3个题都没做出最优的时间和空间,不过好在至少还是做出来了

你可能感兴趣的:(leetcode刷题,leetcode,算法,golang)