LeetCode321场周赛

121 阅读2分钟

周赛复盘

这是我人生中第一次打LeetCode周赛,因为之前都是在刷题得找东西实践下,所以毅然决然的开始每周的周赛之旅,博主软工大三学生,为了准备春招也加入了刷题的大队伍中,接下来对我的这一次周赛进行复盘

周赛过程

第一次周赛刷题难免有点紧张,但是发现这一次周赛的题目并不是很难,在过的过程中有思路但是就是做不出来,这是第一点。第二在刷题的过程中难免会没有仔细阅读题目然后埋头乱写,这是不好的。

题目复盘

image.png

这题需要我们找出中枢整数。首先我的思路就是利用前缀和数组求解因为是和的累加


public int pivotInteger(int n) {
    int nums[] = new int[n + 1];

    for (int i = 1; i <= n; i++) {
        nums[i] = nums[i - 1] + i;
    }
    for (int i = 1; i <= n; i++) {
        if (nums[i] == nums[n] - nums[i - 1]) {
            return i;
        }
    }
    return -1;
}

但参考了竞赛第一名我们可以知道这题可以转化成等差数列问题d = 1 那么通过等差数列和公式可以得出

(i * (i + 1) == (n - i + 1) * (i + n))

那么就是转化成等差数列和问题

public int pivotInteger(int n) {
    for (int i = 1; i <= n; i++) {
        if (i * (i + 1) == (n - i + 1) * (i + n)) {
            return i;
        }
    }
    return -1;
}

那么就可以很轻松的求得题目所需的解

image.png

第二题是一个子序列问题,我最开始想的很麻烦,滑动窗口,kmp都考虑到了,但是发现因为前缀是可以相同的那么只需加上s和t相同的字符个数的条件下的差值即可也就是 先统计二者相同的部分,然后再计算二者相差的个数即可。


public int appendCharacters(String s, String t) {
    int n = s.length();
    int m = t.length();
    int j = 0;
    for (int i = 0; i < n && j < m; i++) {
        if (s.charAt(i) == t.charAt(j)) {
            j++;
        }
    }
    return m - j;
}

image.png

LeetCode6247这题是我感触最大的一题,因为题解的写法让我醍醐灌顶。 首先题目说如果右侧出现一个严格更大的数也就是比左边所有的都大,那么就是可以人认定为这是一个单调递减的链表,那么单调我们可以用到单调栈,而我最开始做这一题的时候是想在在链表上下文章,边判断边修改原链表,但题解的写法是先创建一个虚拟节点dummy

ListNode dummy = new ListNode(Integer.MAX_VALUE);

将该虚拟节点压入单调栈中那么无论如何接下来的节点都小于甚至是等于该节点那么可以进行单调栈的操作

public ListNode removeNodes(ListNode head) {
    Stack<ListNode> stack = new Stack<>();
    ListNode dummy = new ListNode(Integer.MAX_VALUE);
    dummy.next = head;


    //放最大值在栈底
    stack.push(dummy);
    ListNode cur = head;

    while (cur != null) {
        // 单调递减栈,所以需要把小于 curr 得节点都删除
        while (!stack.isEmpty() && cur.val > stack.peek().val) {
            stack.pop();
        }
        stack.peek().next = cur;
        stack.push(cur);
        cur = cur.next;
    }

    return dummy.next;
}

先将节点压入栈中进行判断然后再弹出不符合条件的节点 且将最顶端的链表节点的next指向接入的节点,这一点学习了。

image.png 这题说实话第一眼感觉挺难的但听了题解还是有一点理解了学到了一个等价转化的思路 但还是不是很理解得继续学习下


public int countSubarrays(int[] nums, int k) {
    int pos = 0, n = nums.length;
    while (nums[pos] != k) {
        pos++;
    }

    Map<Integer, Integer> cnt = new HashMap<>();
    // i=pos 的时候 c 是 0,直接记到 cnt 中,这样下面不是大于就是小于
    cnt.put(0, 1);

    for (int i = pos + 1, c = 0; i < n; i++) {
        c += nums[i] > k ? 1 : -1;
        cnt.put(c, cnt.getOrDefault(c, 0) + 1);
    }

    // i=pos 的时候 c 是 0,直接加到答案中,这样下面不是大于就是小于
    int ans = cnt.get(0) + cnt.getOrDefault(1, 0);
    for (int i = pos - 1, c = 0; i >= 0; i--) {
        c += nums[i] < k ? 1 : -1;
        ans += cnt.getOrDefault(c, 0) + cnt.getOrDefault(c + 1, 0);
    }

    return ans;
}

结尾

第一次打周赛确实能发现自己很多的不足,思路不清晰,审题不认真,和平时刷题的感觉大不相同,但这恰恰可以找出我的不足,建议大家可以打打周赛来提升自己提高自己的临场解题能力,第一次写文章写的不是很好,有不足的地方大家多多谅解。