LeetCode 21-24

Problem 21 Merge Two Sorted Lists

合并两个有序队列,这是合并排序中的基础,只是这里把数组换成了队列,主要的思想没有变化。
首先,当有一个队列为空时,返回另一个队列;
若都不为空,则从头开始遍历两个队列,比较对应元素,选择其中较小的元素,将新的队列的指针指向它,将该元素所在队列的指针向后移动以为,如此往复直至其中一个队列的为空
如果一个队列为空,那么将另一个队列直接新队列的后面

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    if (l1 == NULL)
        return l2;
    if (l2 == NULL)
        return l1;
    ListNode* new_head, *move;
    bool first = true;
    while (l1 != NULL && l2 != NULL) {
        if (first) {
            if (l1->val < l2->val) {
                move = new_head = l1;
                l1 = l1->next;
            }
            else {
                move = new_head = l2;
                l2 = l2->next;
            }
            first = false;
            continue;
        }
        if (l1->val < l2->val) {
            move->next = l1;
            l1 = l1->next;
        }
        else {
            move->next = l2;
            l2 = l2->next;
        }
        move = move->next;
    }
    if (l1 != NULL)
        move->next = l1;
    else if (l2 != NULL)
        move->next = l2;
    return new_head;
}

Problem 22 Generate Parentheses

给定小括号的对数n,给出所有的成对组合的可能性。
总体来说,实际上我们只知道每种组合可能的最大长度是 2n ,比较直接的方法就是遍历所有可能性。
这里采用递归的思想来求解。递归函数的参数包括还可以放入多少个括号,存储结果的向量,上层函数产生结果,以及存储括号的栈(这个栈是用来检查是否配对的。简单的思路就是当遇到(时,压栈;当遇到)时,和栈顶的元素比较看是否能配对,如果不能配对则失败。)
每次都一次将last_string + '('last_string + ')'作为下一次函数的参数;对于last_string + ')',首先应该判断加入新的括号之后是否能够配对,如果能够配对则继续,否则返回。
递归结束点有两个:一是之前提到的无法配对;二是当只能放入0个括号时,如果栈为空,那么将last_string放入结果向量中,否则返回。

void recurseGenerate(int n_left, vector<string>& result, string last_string, stack<char> before) {
    if (n_left == 0) {
        if (before.empty())
            result.push_back(last_string);
        return;
    }
    string temp_string = last_string + '(';
    stack<char> temp_stack = before;
    temp_stack.push('(');
    recurseGenerate(n_left - 1, result, temp_string, temp_stack);
    temp_stack = before;
    temp_string = last_string + ')';
    if (!temp_stack.empty() && temp_stack.top() == '(') {
        temp_stack.pop();
        recurseGenerate(n_left - 1, result, temp_string, temp_stack);
    }
    return;
}

vector<string> generateParenthesis(int n) {
    vector<string> result;
    stack<char> before;
    recurseGenerate(2 * n, result, "",before);
    return result;
}

Problem 23 Merge k Sorted Lists

这个问题比较简单的方法就是两个两个合并,直到所有的队列都被合并了,那么最后得到的队列就是有序的。合并的方法之前已经解决过一次,这里不再赘述。

ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
    if (l1 == NULL)
        return l2;
    if (l2 == NULL)
        return l1;
    ListNode* new_head, *move;
    bool first = true;
    while (l1 != NULL && l2 != NULL) {
        if (first) {
            if (l1->val < l2->val) {
                move = new_head = l1;
                l1 = l1->next;
            }
            else {
                move = new_head = l2;
                l2 = l2->next;
            }
            first = false;
            continue;
        }
        if (l1->val < l2->val) {
            move->next = l1;
            l1 = l1->next;
        }
        else {
            move->next = l2;
            l2 = l2->next;
        }
        move = move->next;
    }
    if (l1 != NULL)
        move->next = l1;
    else if (l2 != NULL)
        move->next = l2;
    return new_head;
}

ListNode* mergeKLists(vector<ListNode*>& lists) {
    int size = lists.size();
    if (size == 0) return NULL;
    if (size == 1) return lists[0];
    ListNode* new_head = NULL;
    for (int i = 0; i < size; i++) {
        new_head = mergeTwoLists(new_head, lists[i]);
    }
    return new_head;
}

Problem 24 Swap Nodes in Pairs

这道题还是挺简单的,就两种情况:
第一种是头上的节点需要交换。
这时候需要记录下第三个节点的位置,然后把第二个节点向后指向头,头向后指向第三个节点;
第二种情况是中间的两个节点需要交换。
这时候需要记录下前一个节点,和第三个节点的位置,然后前一个节点向后指向第二个节点,第二个节点向后指向第一个节点,第一个节点向后指向第三个节点。

最后组成一个递归算法,当第一个节点为null或者第二个节点为null时递归结束。

void recursiveSwap(ListNode* before_head, ListNode* current_head) {
    if (current_head == NULL || current_head->next == NULL) return;
    ListNode* second = current_head->next, *next_head, *before;
    current_head->next = second->next;
    second->next = current_head;
    before_head->next = second;
    next_head = current_head->next;
    before = current_head;
    recursiveSwap(before, next_head);
}

ListNode* swapPairs(ListNode* head) {
    if (head == NULL || head->next == NULL) return head;
    ListNode* second = head->next, *next_head, *before;
    head->next = second->next;
    second->next = head;
    next_head = head->next;
    before = head;
    recursiveSwap(before, next_head);
    return second;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值