「LeetCode」第 267 场周赛(上)

165 阅读1分钟

这是我参与11月更文挑战的第12天,活动详情查看2021最后一次更文挑战

链接

leetcode-cn.com/contest/wee… 周赛一共四道题,今天是前两道题的解析。

题目

5926. 买票需要的时间

简单模拟

解析

按照排队流程走一遍,即可,逐个逐轮减去买一张票的次数,直至第k个人要买的票为0即可。

代码

class Solution {
public:
    int timeRequiredToBuy(vector<int>& tickets, int k) {
        queue<int> q;
        int n = tickets.size();
        for (int i = 0; i < n; ++i)
            q.emplace(i);
        int t = 0;
        while (tickets[k]) {
            int u = q.front();
            q.pop();
            tickets[u]--;
            t++;
            if (tickets[u])
                q.emplace(u);
        }
        return t;
    }
};

一次遍历

解析

分析排队流程,即可得出在第k个人之前的人最多买tickets[k]张票,在第k个人之后的人最多买tickets[k]-1张票;遍历一次数组做一个大小值比较即可。

代码

class Solution:
    def timeRequiredToBuy(self, tickets: List[int], k: int) -> int:
        kNum = tickets[k]
        ans = 0
        for i in range(0, len(tickets)):
            if i <= k:
                ans += min(kNum, tickets[i])
            else:
                ans += min(kNum-1, tickets[i])
        return ans

5927. 反转偶数长度组的节点

链表模拟,分情况讨论

解析

反转链表的题LeetCode上有很多,大部分都是用到类似的技巧:记住每次遍历操作上一个节点的引用,在此基础上循环删除和插入节点;主要要注意的点就是头节点的处理、利用临时变量断开指针和指向另一个指针的顺序,以及到链表尾部的判断。

此题还有一点需要注意的就是对“每个 偶数 长度组”的理解,可能会导致对末尾情况处理的不一致。

代码

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseEvenLengthGroups(self, head: Optional[ListNode]) -> Optional[ListNode]:
        prevP, p = None, head
        step = 1
        while p:
            forwardP = p
            maxStep, realStep = step, 0
            while forwardP and maxStep > realStep:
                forwardP = forwardP.next
                realStep += 1
            if realStep % 2 == 1:
                thisTurnStep = realStep
                while p and thisTurnStep > 0:
                    thisTurnStep -= 1
                    prevP, p = p, p.next
            else:
                thisTurnStep = realStep
                while p.next and thisTurnStep > 1:
                    thisTurnStep -= 1
                    nextP = p.next
                    p.next = nextP.next
                    nextP.next = prevP.next
                    prevP.next = nextP
                prevP, p = p, p.next
            step += 1
        return head

数组模拟

解析

对链表的操作会不方便,使用数组来存储然后反转的话就很方便了。

代码

class Solution {
public:
    ListNode* reverseEvenLengthGroups(ListNode* head) {
        vector<int> v;
        ListNode *p = head;
        while (p != nullptr) {
            v.emplace_back(p->val);
            p = p->next;
        }
        
        int n = v.size();
        int i = 0, g = 1;
        while (i < n) {
            if (g > n - i)
                g = n - i;
            if (g % 2 == 0)
                reverse(v.begin() + i, v.begin() + i + g);
            i += g;
            g++;
        }
        
        p = head;
        for (int vi : v) {
            p->val = vi;
            p = p->next;
        }
        
        return head;
    }
};