LeetCode算法练习——链表(一)

LeetCode206. 反转链表

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

该题虽然为链表的基础操作,但是听说面试很常考,逻辑也很容易出错。我们需要两个指针,一个作为游标,一个作为反转链表的头节点,操作示意图如下:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *pre = head, *cur = NULL;   
        while(pre){
            ListNode *tmp = pre->next;
            pre->next = cur;
            cur = pre;
            pre = tmp;
        }
        return cur;
    }
};

LeetCode2. 两数相加

给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

此题的思想和大数相加类似,两个链表同时进行遍历,相应数值累加,我们需要考虑一个进位carry。

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *l3 = new ListNode(0);
        ListNode *curr = l3;
        int carry = 0;
        while(l1 != NULL || l2 != NULL){
            int sum = 0;
            int x = 0, y = 0;
            //遍历两个链表
            if(l1){
                x = l1->val;
                l1 = l1->next;
            }
            if(l2){
                y = l2->val;
                l2 = l2->next;
            }
            sum = x + y + carry;                    //数位求和
            carry = sum/10;                         //进位计算
            curr->next = new ListNode(sum % 10);    //申请新节点并赋值
            curr = curr->next;                      //新节点遍历
        }
        if(carry){                                  //如果最高位需要进位
            curr->next = new ListNode(1);
        }
        return l3->next;  
    }
};

LeetCode19. 删除链表的倒数第N个节点

给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

此题思路很简单,我们需要两个指针,0第一个指针在原链表上遍历k次,随后两个指针同时向后遍历,当第一个遍历结束时,第二个指针也就到达了倒数第k个位置。当然,此题我们也可以将节点摘取存入容器内进入操作,代码也在下面给出了。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *tmp = new ListNode(0);
        tmp->next = head;
        ListNode *p = tmp;
        ListNode *q = tmp;
        for(int i = 0; i < n; i++){
            p = p->next;
        }
        while(p->next){
            p = p->next;
            q = q->next;
        }
        q->next = q->next->next;
        return tmp->next;
        /*方法2
        vector<ListNode*> vec;
        while(head->next != nullptr)
        {
            vec.push_back(head);                //把链表中的所有节点放到vector中
            head = head->next;
        }
        vec.push_back(head);                    //别忘了最后一个节点
        vec.erase(vec.begin() + vec.size() - n);    //删掉要求的那个节点
        if(vec.size() == 0){return nullptr;}
        for(int i = 0 ; i < vec.size()-1 ; i ++)
        {
            vec[i]->next = vec[i + 1];            //将容器内的点前后相连
        }
        vec[vec.size() - 1]->next = nullptr;      //最后一个节点确保next为空
        return vec[0];                          //返回第一个节点即可
        */
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章