1.加油站
1.1 自解
自己思路:gas-cost,得到从这个站出发——一直到达下一个站,能够剩余的汽油。
找出最大连续子串的起始位置即可。
func canCompleteCircuit(gas []int, cost []int) int {
n := len(gas)
remain := make([]int,n)
sum := 0
for i:=0;i<n;i++{
remain[i] = gas[i]-cost[i]
sum+=remain[i]
}
if sum<0{
return -1
}
startIndex := 0
sum,maxSum := 0,-1
i := 0
loopNum:=0
for {
sum = sum + remain[i]
if sum<remain[i]{
startIndex = i
sum = remain[i]
}
if sum>maxSum{
maxSum = sum
}
if loopNum==1{
break
}
i++
if i%n==0{
loopNum++
i = 0
}
}
return startIndex;
}
1.2 他解
如果总油量减去总消耗大于等于零那么一定可以跑完一圈,说明 各个站点的加油站 剩油量rest[i]相加一定是大于等于零的。
每个加油站的剩余量rest[i]为gas[i] - cost[i]。
i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。
func canCompleteCircuit(gas []int, cost []int) int {
curSum := 0
totalSum := 0
start := 0
for i := 0; i < len(gas); i++ {
curSum += gas[i] - cost[i]
totalSum += gas[i] - cost[i]
if curSum < 0 {
start = i+1
curSum = 0
}
}
if totalSum < 0 {
return -1
}
return start
}
2.分发糖果
2.1 他解
先处理正序,再处理反序
package main
func candy(ratings []int) int {
n := len(ratings)
candies := make([]int, n)
for i := 1; i < n; i++ {
if ratings[i] > ratings[i-1] {
candies[i] = candies[i-1] + 1
}
}
for i := n - 1; i >= 1; i-- {
if ratings[i-1] > ratings[i] {
candies[i-1] = max(candies[i-1], candies[i]+1)
}
}
sum := n
for i := 0; i < n; i++ {
sum += candies[i]
}
return sum
}
func main() {
nums := []int{1, 0, 2}
candy(nums)
}
3.柠檬水找零
思路:优先使用10块的
func lemonadeChange(bills []int) bool {
num5, num10 := 0, 0
for i := 0; i < len(bills); i++ {
if bills[i] == 5 {
num5++
} else if bills[i] == 10 {
if num5<=0{
return false
}
num10++
num5--
} else if bills[i] == 20 {
if num10>0 && num5>0{
num10--
num5--
}else if num5>=3{
num5-=3
}else{
return false
}
}
}
return true
}
4.根据身高重建队列
按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。
所以在按照身高从大到小排序后:
- 局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性
- 全局最优:最后都做完插入操作,整个队列满足题目队列属性
func reconstructQueue(people [][]int) [][]int {
sort.Slice(people, func(i, j int) bool {
if people[i][0] == people[j][0] {
return people[i][1] < people[j][1] // 当身高相同时,将K按照从小到大排序
}
return people[i][0] > people[j][0] // 身高按照由大到小的顺序来排
})
// 再按照K进行插入排序,优先插入K小的
for i, p := range people {
copy(people[p[1]+1:i+1], people[p[1]:i]) // 空出一个位置
people[p[1]] = p
}
return people
}