最近一些算法题的总结
发布日期:2021-05-07 16:07:33 浏览次数:11 分类:精选文章

本文共 2925 字,大约阅读时间需要 9 分钟。

技术文章

交点问题

对于两个有序列表的交点问题,可以使用双指针法来解决。这种方法简单且高效。双指针分别从两个列表的头部开始移动。当其中一个指针达到列表末尾时,另一个指针会被移动到对方列表的头部。这种方法的时间复杂度为 O(n),其中 n 是两个列表的长度。

代码示例如下:

class Solution {    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {        ListNode p1 = headA;        ListNode p2 = headB;        while (p1 != p2) {            p1 = (p1 != null) ? p1.next : headB;            p2 = (p2 != null) ? p2.next : headA;        }        return p1;    }}

摩尔投票算法

摩尔投票算法是一种有效的找出数组中多数元素(众数)的方法。该算法通过给予候选元素“票数”,逐步筛选出众数。具体步骤如下:

  • 初始化变量 xvote,前者用于存储当前候选元素,后者用于记录投票情况。
  • 遍历数组中的每个元素:
    • 如果是第一个元素,设置 x 为当前元素并初始化投票为 1。
    • 对于后续元素,根据当前元素与 x 相同或不同的情况,分别增加或减少投票。
  • 当所有元素处理完毕后,x 即为众数。
  • 代码示例如下:

    class Solution {    public int majorityElement(Vector
    nums) { int x = 0, vote = 0; for (int val : nums) { if (vote == 0) { x = val; } if (x == val) { vote++; } else { vote--; } } return x; }}

    栈模拟序列化

    序列化问题可以通过栈来模拟。栈用于跟踪当前处理的节点,并管理节点的插入位置。具体规则如下:

  • 遍历 preorder 字符串:
    • 如果当前字符为空('-'),表示空节点,直接处理。
    • 如果遇到分隔符('-'),表示当前节点的结束,弹出栈顶元素并减少槽的数量。
    • 如果遇到有意义的节点,压入栈并增加槽的数量。
  • 遇到未处理完的节点时,若栈为空,说明序列化失败。
  • 代码示例如下:

    class Solution {    public bool isValidSerialization(String preorder) {        int index = 0;        Stack
    st = new Stack<>(); st.push(1); while (index < preorder.length()) { if (st.isEmpty()) { return false; } if (preorder.charAt(index) == ',') { index++; } else if (preorder.charAt(index) == '#') { st.top--; if (st.top == 0) { st.pop(); } index++; } else { while (index < preorder.length() && preorder.charAt(index) != ',') { index++; } if (index >= preorder.length()) { return false; } st.top--; if (st.top == 0) { st.pop(); } st.push(2); } } return st.isEmpty(); }}

    零和博弈

    零和博弈问题可以通过递归方法解决。该方法基于极大极小策略,具体步骤如下:

  • 如果只剩一个元素,直接返回该元素。
  • 计算左边子树和右边子树的结果。
  • 选择使得当前玩家获得最大收益的策略。
  • 代码示例如下:

    class Solution {    int first(const vector
    & nums, int left, int right) { if (left == right) { return nums[left]; } return max(nums[left] + second(nums, left + 1, right), nums[right] + second(nums, left, right - 1)); } int second(const vector
    & nums, int left, int right) { if (left == right) { return 0; } return min(first(nums, left + 1, right), first(nums, left, right - 1)); } public bool PredictTheWinner(const vector
    & nums) { return first(nums, 0, nums.size() - 1) >= second(nums, 0, nums.size() - 1); }}

    以上是本文的全部内容,涵盖了交点问题、摩尔投票算法、栈模拟序列化以及零和博弈的解决方案。

    上一篇:动态规划的学习—从暴力递归到动态规划
    下一篇:握手中少了次握手客户端和服务端会做什么?

    发表评论

    最新留言

    初次前来,多多关照!
    [***.217.46.12]2025年04月02日 19时32分07秒