LeetCode日记20200203

LeetCode日记2020.2.3


链表最后一天

19 删除链表的倒数第N个节点(mid)

两种解法。
双指针迭代:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyH = new ListNode(-1);
        dummyH->next = head;
        ListNode *fast = dummyH, *slow = dummyH; 
        while(fast->next!=NULL)
        {
            fast = fast->next;
            if(!(--n>=0))
                slow = slow->next;  
        }
        slow->next = slow->next->next;
        return dummyH->next;
    }
};

递归回溯:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head==NULL)
            return head;

        ListNode* newHead = removeNthFromEnd(head->next, n);
        ++cnt;
        if(cnt==n)
            return newHead;
        else
        {
            head->next = newHead;
            return head;
        }  
    }

    int cnt=0;
};

2 两数相加(mid)

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* dummyH = new ListNode(-1);
        ListNode* End = dummyH;
        int carry = 0;
        while(l1!=NULL||l2!=NULL)
        {
            int a = l1==NULL?0:l1->val;
            int b = l2==NULL?0:l2->val;
            int sum = a+b+carry;
            carry = sum/10;
            sum%=10;
            End -> next = new ListNode(sum);
            End=End->next;
            l1 = l1==NULL?NULL:l1->next;
            l2 = l2==NULL?NULL:l2->next;
        }
        if(carry>0)
            End->next = new ListNode(carry);

        return dummyH->next;    
    }
};

1171 从链表中删去总和值为零的连续节点(mid)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeZeroSumSublists(ListNode* head) {
        ListNode* dummyH = new ListNode(0);
        dummyH->next = head;
        map<int, ListNode*> sumMap;
        int cnt = 0;
        int sum = 0;
        ListNode* End = dummyH;
        while(End !=NULL)
        {
            sum += End -> val;
            sumMap[sum] = End;
            ++cnt;
            End = End->next;
        }

        End = dummyH;
        sum = 0;
        while(End != NULL)
        {
            sum += End->val;
            End->next = sumMap[sum]->next;
            End=End->next;
        }
        return dummyH->next;
    }
};

1290 二进制链表转整数(easy)

class Solution {
public:
    int getDecimalValue(ListNode* head) {
        int val = 0;
        while(head!=NULL)
        {
            val <<= 1;
            val += head->val;
            head = head->next;
        }
        return val; 
    }
};

206 反转链表(easy)

递归反转

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==NULL)
            return head;

        ListNode* newEnd = reverseSubList(head);
        newEnd->next = NULL;
        return rhead;
    }

    ListNode* reverseSubList(ListNode* head){
        if(head->next == NULL)
        {
            rhead = head;
            return head;
        }
        ListNode* newEnd = reverseSubList(head->next);
        newEnd->next = head;
        return head;
    }

    ListNode* rhead;
};

876 链表的中间节点(easy)

记住:快慢指针起点均为head时,快指针终止迭代时

fast==NULL||fast->next==NULL

若链表长度为偶数则慢指针位于后半部头节点,若长度为奇数则慢指针恰好位于链表中间。

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
         ListNode* slow = head, *fast = head;
         while(fast!=NULL&&fast->next!=NULL)
         {
             fast = fast->next->next;
             slow = slow->next;
         }
         return slow;
    }
};

160 相交链表(easy)

和环形链表相似,最好用双指针解决,技巧性很强。
第一个是官方解法,其实当hA,hB移动到末尾时重定位到各自的链表头也可以得到正确结果,但耗时长需要更多循环(循环次数为两个链表长度的最小公倍数减相交部分长度),交叉重定位只需要重定位一次(循环次数为两个链表长度之和减相交部分长度)。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        auto hA = headA;
        auto hB = headB;
        while(hA!=hB)
        {
            hA = hA==NULL?headB:hA->next;
            hB = hB==NULL?headA:hB->next;
        }
        return hA;
    }
};

第二个是自己的解法,本质上与官方题解一样,思路还是不够简洁。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        auto hA = headA;
        auto hB = headB;
        while(hA!=NULL&&hB!=NULL)
        {
            hA = hA->next;
            hB = hB->next;
        }
        auto c = hA==NULL?hB:hA;
        auto hL = hA==NULL?headB:headA;
        auto hS = hA==NULL?headA:headB;
        while(c!=NULL)
        {
            c=c->next;
            hL=hL->next;
        }
        while(hL!=hS)
        {
            hL=hL->next;
            hS=hS->next;
        }
        return hL;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值