Leetcode 10:正则表达式匹配

题目描述

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘* ‘ 的正则表达式匹配。

题目解析

详见:https://leetcode-cn.com/problems/regular-expression-matching/solution/c-ji-yi-hua-shen-du-you-xian-sou-suo-by-da-li-wa-2/

代码实现

class Solution {public:    vector<vector<int>> mem;    int dfs(const string& s, const string& p, int i, int j) {        if (i == s.size()) return j == p.size() ? 1 : -1;        if (j == p.size()) return i == s.size() ? 1 : -1;        if (mem[i][j] != 0) return mem[i][j];        if (j == p.size() - 1 || p[j + 1] != '*') {            if (p[j] == '.' || p[j] == s[i]) {                mem[i][j] = dfs(s, p, i + 1, j + 1);                return mem[i][j];            }        } else {            if (dfs(s, p, i, j + 2) > 0) {                mem[i][j] = 1;                return mem[i][j];            }            if (p[j] == '.' || p[j] == s[i]) {                bool t = dfs(s, p, i + 1, j + 2) > 0 || dfs(s, p, i + 1, j) > 0;                mem[i][j] = t ? 1 : -1;                return mem[i][j];            }        }        mem[i][j] = -1;        return mem[i][j];    }    bool isMatch(string s, string p) {        s += '#';        p += '#';        mem = vector<vector<int> >(s.size(), vector<int>(p.size(), 0));        return dfs(s, p, 0, 0) > 0;    }};

耗时&内存占用

复杂度分析

Leetcode 21:合并两个有序链表

题目描述

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

解题思路

不需要多说,直接看代码就看得懂,这是迭代法。递归法曾经在博客发过,具体可以在博客里面搜索一下。

代码实现

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2){    ListNode* head = new ListNode(-1);    ListNode* p = head;    while (l1!=nullptr && l2!=nullptr) {        if (l1->val <= l2->val)        {            head->next = l1;            l1 = l1->next;        }        else {            head->next = l2;            l2 = l2->next;        }        head = head->next;    }    head->next = l1 ? l1 : l2;    return p->next;}

耗时和内存消耗

复杂度分析

Leetcode 23:合并K个排序链表

题目描述

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例

输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6

解题思路

其实解题思路有很多,例如链表全部push到一个vector后然后排序,最后再转换成一个list,这个复杂度是O(n^2),这是我想到的方法,但是这个方法太麻烦,复杂度太高。

另外一种思想就是合并数组中第k个链表到第1个链表,合并数组中第k-1个链表到第2个链表,依次这样操作;一轮合并之后,新链表分布在数组的 第1 到 第(k+1)/2个链表中,继续1这样的合并直到新链表只在数组第一个位置。这种方法是时间复杂度为O(N* log(k)),其中k为链表个数,N为链表平均长度。

还有一种思想是首先将vector转化为queue,然后在queue中每次取出前两个链表,按照之前简单的两个链表合并的方式进行合并,将合并完之后的链表push到queue的最后。依次这样进行,其实和上面的方法思路总体上是一样的,只不过用了一个queue来做中间变量。

下面是这种方法的实现。

代码实现

 ListNode* mergetwoLists(ListNode* l1, ListNode* l2){    ListNode* head = new ListNode(-1);    ListNode* p = head;    while (l1 && l2) {        if (l1->val < l2->val)        {            head->next = l1;            l1 = l1->next;        }        else {            head->next = l2;            l2 = l2->next;        }        head = head->next;    }    head->next = l1 ? l1 : l2;    return p->next;}ListNode* mergeKLists(vector<ListNode*>& lists) {    int numoflist = lists.size();    if (numoflist == 0)        return nullptr;    if (numoflist == 1)        return lists[0];    queue<ListNode*> temp(deque<ListNode*>(lists.begin(), lists.end()));    //将vector转化为队列    //如果队列元素大于1,则拿两个合并,合并后的链表继续添加到链表尾部    while (temp.size() > 1)    {        ListNode* temp1 = temp.front();        temp.pop();        ListNode* temp2 = temp.front();        temp.pop();        temp.push(mergetwoLists(temp1, temp2));    }    return temp.front();}

复杂度

复杂度分析

Leetcode 31:下一个排列

题目描述

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

解题思路

详见:
https://leetcode-cn.com/problems/next-permutation/solution/xia-yi-ge-pai-lie-by-leetcode/

代码实现

void reve(vector<int>& nums, int start){    int i = start, j = nums.size() - 1;    while (i < j)    {        swap(nums[i], nums[j]);        i++;        j--;    }}void nextPermutation(vector<int>& nums) {    int i = nums.size() - 2;    while (i >= 0 && nums[i + 1] <= nums[i])    {        i--;    }    if (i >= 0)    {        int j = nums.size() - 1;        while (j >= 0 && nums[j] <= nums[i])        {            j--;        }        swap(nums[i], nums[j]);    }    reve(nums,i+1);}

复杂度

时间复杂度:O(n)
空间复杂度:O(1)

复杂度分析