• 八月集训day05——链表 + 双指针


    2. 两数相加—链表

    代码/思路

    思路:链表的遍历 / 按位相加

    1. 直接相加两个链表对应的元素
    2. 用carry来处理进位
    3. 最后记得加上最后一次进位
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
            //初始化两个节点,一个头节点,一个尾节点
            ListNode* head = nullptr;
            ListNode* tail = nullptr;
            //用carry记录进位
            int carry = 0;
            //两个链表,其中一个有值就进行计算
            while(l1 || l2)
            {
    			//先走完的链表后续元素的值就当作0
                int n1 = l1 ? l1->val : 0;
                int n2 = l2 ? l2->val : 0;
                int sum = n1 + n2 + carry;
    
                //如果头结点为空
                if(!head)
                {
                    head = tail = new ListNode(sum % 10);
                }
                else
                {
                    tail->next = new ListNode(sum % 10);
                    tail = tail->next;
                }
                carry = sum / 10;
                //移动指针
                if(l1)
                {
                    l1 = l1->next;
                }
                if(l2)
                {
                    l2 = l2->next;
                }
            }
            //最后别忘记加上最后一个进位
            if(carry)
            {
                tail->next = new ListNode(carry);
            }
            return head;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    3. 无重复字符的最长子串

    代码/思路

    思路:滑动窗口 / 双指针

    1. 滑动窗口
    2. 遍历每个元素做为做指针,在增加右指针的过程中
    3. 看集合是否存在重复的元素
    4. 若存在则更新结果,并改变左指针重复操作
    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            unordered_set<char> hash;
            int res = 0;
            int r = -1;
            for(int i = 0; i < s.size(); i++)
            {
                if(i)
                {
                    hash.erase(s[i - 1]);
                }
                while(r + 1 < s.size() && !hash.count(s[r + 1]))
                {
                    hash.insert(s[r + 1]);
                    r++;
                }
                res = max(res, r - i + 1);
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    524. 通过删除字母匹配到字典里最长单词

    代码/思路

    思路: 双指针——数组同向追赶

    1. 先把数组按照字母数降序排列,字典序升序排列
    2. 然后遍历数组每个元素,定义双指针i, j 分别指向s 和 t 的每个元素
    3. 当 s[i] == s[t] 时才增加 j
    4. 否则一直增加 i
    5. 最后如果 j 刚好等于 t 的长度,则返回 t 这个字符串
    /**
     * @param {string} s
     * @param {string[]} dictionary
     * @return {string}
     */
    var findLongestWord = function(s, dictionary) {
          dictionary.sort((words1, words2) => {
                if(words1.length == words2.length)
                {
                    return words1.localeCompare(words2);
                }
                return words2.length - words1.length;
            })
    
            for(const t of dictionary)
            {
                let i = 0;
                let j = 0;
                while(i < s.length && j < t.length)
                {
                    if(s[i] === t[j])
                    {
                        j++;
                    }
                    i++;
                }
                if(j == t.length)
                {
                    return t;
                }
            }
            return "";
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    1679. K 和数对的最大数目

    代码/思路

    思路:双指针直接做

    1. 双指针分别指向头尾元素
    class Solution {
    public:
        int maxOperations(vector<int>& nums, int k) {
            sort(nums.begin(), nums.end());
            int l = 0;
            int r = nums.size() - 1;
            int res = 0;
            while(l < r)
            {
                int t = nums[l] + nums[r];
                if(t == k)
                {
                    l++;
                    r--;
                    res++;
                }
                else if(t < k)
                {
                    l++;
                }
                else if(t > k)
                {
                    r--;
                }
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
  • 相关阅读:
    Qt中常用对话框
    object-fit的属性
    加密,各种加密,耙梳加密算法(Encryption)种类以及开发场景中的运用(Python3.10)
    Java-JDBC
    【无标题】
    使用nexus上传jar包图文教程
    一文拿捏线程和线程池的创建方式
    java programer future plan
    k8s命令行web代理神器gotty
    c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现)
  • 原文地址:https://blog.csdn.net/m0_52336986/article/details/126185287