八月集训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;
    }
};

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;
    }
};

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 "";
};

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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值