LeetCode其他链表简单题

其他链表简单题

160. Intersection of Two Linked Lists

Write a program to find the node at which the intersection of two singly linked lists begins.

For example, the following two linked lists:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3
begin to intersect at node c1.

Notes:
- If the two linked lists have no intersection at all, return null.
- The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
要求两链表的交集(不是严格意义上的交集,而是从某个结点开始到链表尾元素都相同)。
解法1:分别求两链表的长度len1、len2。然后对齐两链表尾:让指针从较长的链表头部先移动 |len1-len2| 步,然后和较短的链表逐一比较。
解法2:不需要求链表长度。用快慢指针找到两链表尾对齐时,长链表对应短链表头部的位置。然后接下来进行逐一比较了。

网上看了很多版本,包括leetcode的discuss,大多都是找到第一个交点就结束后续检查了,但我觉得这样不是很严谨,万一之后存在结点的值不一样的情况呢?下面的写法啰嗦了一点,但效率不差。

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if (!headA || !headB) return NULL;
        ListNode *pA1 = headA, *pB1 = headB;
        ListNode *p2 = NULL, *subHead = NULL;
        if (!pA1)
        {
            p2 = headB;
            while (pB1)
            {
                pB1 = pB1->next;
                p2 = p2->next;
            }
            pA1 = headA;
            subHead = p2;
            while (p2)
            {
                if (p2->val != pA1->val) subHead = p2->next;
                p2 = p2->next;
                pA1 = pA1->next;
            }
        }
        else if (!pB1) {
            p2 = headA;
            while (pA1)
            {
                pA1 = pA1->next;
                p2 = p2->next;
            }
            subHead = p2;
            pB1 = headB;
            while (p2)
            {
                if (p2->val != pB1->val) subHead = p2->next;
                p2 = p2->next;
                pB1 = pB1->next;
            }
        }
        return subHead;
    }

203. Remove Linked List Elements

删除链表中值为val的元素

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if (!head) return head;
        ListNode **pp = &head;
        while (*pp)
        {
            if ((*pp)->val == val) {
                ListNode *del = *pp;
                *pp = del->next;
                delete del;
            }
            else
            {
                pp = &((*pp)->next);
            }
        }
        return head;
    }
};

234. Palindrome Linked List

Given a singly linked list, determine if it is a palindrome.

Follow up:
Could you do it in O(n) time and O(1) space?
判断一个链表是否是回文链表(即顺着读和倒着读是一样的)。

根据回文的特点,首先要找到链表的中点,然后比较对应位置的数是否相等。找中点可以利用快慢指针来实现(慢指针跑一步,快指针就跑两步,当快指针走完时慢指针就到达链表中点了)。然后很容易想到栈先进后出的特点,把慢指针每走一步的值都压进栈,最后栈中存入的是链表前半部分的值。之后就可以和链表后半部分的值进行顺序比较判断是否回文了。

但是这道题Follow Up让我们用O(1)的空间,显然上述上述方法不能达到要求,那么不能使用栈那应该怎么做呢?我们利用的是栈先进后出的特点,如果把链表后半部分进行反转也可以达到相同的目的。之后我们把前半部分、后半部分链表按顺序比较即可判断是否回文了:

bool isPalindrome(ListNode* head) {
        if (!head || !head->next) return true;
        //找链表中点
        ListNode *slow = head, *fast = head;
        while (fast->next && fast->next->next)
        {
            slow = slow->next;
            fast = fast->next->next;
        }
        //逆序后半部分
        ListNode *subHead = slow->next ,*cur;
        while ((cur = subHead->next))
        {
            subHead->next = cur->next;
            cur->next = slow->next;
            slow->next = cur;
        }
        //比较
        ListNode *p = head;
        while (slow->next)
        {
            if (p->val != slow->next->val) return false;
            p = p->next;
            slow = slow->next;
        }
        return true;
    }

237. Delete Node in a Linked List

Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.

Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function.

删除一个链表中给定的结点(除尾结点外),唯一的参数就是要删除的那个结点。

        void deleteNode(ListNode* node) {
        node->val = node->next->val;
        ListNode *del = node->next;
        node->next = node->next->next;
        delete del;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值