LeetCode链表

链表

两数相加

添加一个有默认值的参数cnt,递归完成结果

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2, int cnt = 0) {
        if(l1 == nullptr && l2 == nullptr)
        {
            if(cnt == 0) return nullptr;
            else return new ListNode(cnt);
        }
        if(l1 == nullptr) l1 = new ListNode(0);
        if(l2 == nullptr) l2 = new ListNode(0);
        int sum = l1->val + l2->val + cnt;
        ListNode* head = new ListNode(sum % 10);
        head->next = addTwoNumbers(l1->next, l2->next, sum / 10);
        return head;
    }
  
};

237. 删除链表中的节点 - 力扣(LeetCode)

class Solution {
public:
    void deleteNode(ListNode* node) {
        if(!node->next)
        {
            return;
        }
        else if(!node->next->next)
        {
             node->val = node->next->val;
             node->next = NULL;
        }
        else
        {
            node->val = node->next->val;
            deleteNode(node->next);
        }
    }
};

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

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* fast = head;
        ListNode* low = head;
        ListNode* last;
        while(n --) fast = fast->next;
        if(fast == nullptr) return head->next;
        while(fast != nullptr)
        {
            fast = fast->next;
            last = low;
            low = low->next;
        }
        last->next = low->next;
        return head;
    }
};

合并有序链表

class Solution {
public:
    //合并两个链表
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* head = new ListNode();
        ListNode* t = head;
        while(list1 != nullptr && list2 != nullptr)
        {
            if(list1->val < list2->val)
            {
                head->next = list1;
                list1 = list1->next;
            }
            else 
            {
                head->next = list2;
                list2 = list2->next;
            }
            head = head->next;
        }
        if(list1 != nullptr) head->next = list1;
        if(list2 != nullptr) head->next = list2;

        return t->next;
    }
};

合并k个升序链表

二分合并

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(!lists.size()) return nullptr;
        int num1 = 0, num2 = 1;
        while(lists.size() - num1 > 1)
        {
            auto a = lists[num1];
            auto b = lists[num2];
            num1 += 2;
            num2 += 2;
            lists.push_back(mergeTwoLists(a, b));
        }
        return lists[lists.size() - 1];
    }
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        ListNode* head = new ListNode();
        ListNode* t = head;
        while(list1 != nullptr && list2 != nullptr)
        {
            if(list1->val < list2->val)
            {
                head->next = list1;
                list1 = list1->next;
            }
            else 
            {
                head->next = list2;
                list2 = list2->next;
            }
            head = head->next;
        }
        if(list1 != nullptr) head->next = list1;
        if(list2 != nullptr) head->next = list2;

        return t->next;
    }
};

反转链表

在这里插入图片描述

回溯法
函数的意义是返回翻转后的链表头。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head == nullptr || head->next == nullptr)
            return head;
        ListNode *newhead = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return newhead;
    }
};

迭代法
制造一个空的 pre 节点用来存储前一个节点

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head) return head;
        ListNode *pre  = nullptr;
        while(head)
        {
            ListNode *ne = head->next;
            head->next = pre;
            pre = head;
            head = ne;
        }
        return pre;
    }
};

反转链表II

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
		ListNode *q = head, *p, *r, *temp_head = nullptr, *temp_tail;//将temp_head初始化为NULL。
		for(int i = 1; i < left; i++){
			if(i == left - 1)temp_head = q;//找到left的前驱,将temp_head指向它。
			q = q->next;
		}
		temp_tail = q;//temp_tail指向left节点
		p = temp_head;//p就位
		r = q->next;//r就位
		for(int i = left; i < right; i++){//开始翻转
			q->next = p;
			p = q;
			q = r;
			r = r->next;
		}
        q->next = p;//最后一个要翻转的节点在循环里没有涉及到,这里出来了处理一下。
		if(temp_head)temp_head->next = q;//只有left不是head节点时才执行。
		temp_tail->next = r;
		return temp_head ? head : q;//返回值判断一下再返回
    }
};

删除元素

在这里插入图片描述
回溯法

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head == nullptr || head->next == nullptr)
            return head;
        ListNode *p = head;
        if(head->val == head->next->val)//如果相等就要删除head的下一个。
        {
            head->next = head->next->next;
            deleteDuplicates(head);
        }
        else
        deleteDuplicates(head->next);//不相等说明head已经是不重复的了,进行下一个。
        return p;
    }
};

迭代法,与回溯法思路一致

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode *p = head;
        while(head&&head->next)
        {
            if(head->val == head->next->val)
                head->next = head->next->next;
            else
                head = head->next;
        }
        return p;
    }
};

删除元素II

在这里插入图片描述

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head == nullptr || head->next == nullptr)return head;
        if(head->val == head->next->val)
        {
            head = deletenode(head, head->val);//删除当前重复节点并找到新head
            head = deleteDuplicates(head);//继续检查新head是否需要删除
        }
        else
            head->next = deleteDuplicates(head->next);//不需要删除head就检查下一个节点并将head连接到新节点
        return head;
    }
    ListNode* deletenode(ListNode* head, int x)
    {
        while(head && head->val == x)
            head = head->next;
        return head;
    }
};

203. 移除链表元素 - 力扣(LeetCode)

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if(head == nullptr) return nullptr;
        if(head->val == val)
            return removeElements(head->next, val);
        head->next = removeElements(head->next, val);
        return head;
    }
};

两两交换链表节点

在这里插入图片描述

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head || !head->next)return head;
        ListNode *newhead = head->next;
        head->next = swapPairs(newhead->next);
        newhead->next = head;
        return newhead;
    }
};
//-----------------------------------------
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head->next == nullptr)
            return head;
        ListNode* h = new ListNode();
        h->next = head->next;
        head->next = swapPairs(head->next->next);
        h->next->next = head;
        return h->next;
    }
};

K个一组翻转链表


class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* dum = new ListNode();
        dum->next = head;
        ListNode* cur = dum;
        while(cur != nullptr)
        {
            reverse(cur, k);
            int u = k;
            while(u-- > 0 && cur != nullptr) cur = cur->next;
        };
        return dum->next;
    }
    void reverse(ListNode* root, int k)
    {
        int u = k;
        ListNode* cur = root;
        while(u -- > 0 && cur != nullptr) cur = cur->next;
        if(cur == nullptr) return;

        ListNode* tail = cur->next;
        ListNode* a = root->next;
        ListNode* b = a->next; //三个指针
        //中间有k - 1个指针需要翻转
        while(k -- > 1)
        {
            ListNode* c = b->next;
            b->next = a;
            a = b;
            b = c;
        }
        root->next->next = tail;
        root->next = a;
    }
};

旋转链表

class Solution {
public:
    //成环再断开
    ListNode* rotateRight(ListNode* head, int k) {
        if(head == nullptr) return nullptr;
        int n = 0;
        ListNode* p = head;
        while(p->next != nullptr)
        {
            n ++;
            p = p->next;
        }
        n ++;
        k = k % n;
        p->next = head;
        k = n - k;
        while(k -- > 1)
        {
            head = head->next;
        }
        p = head->next;
        head->next = nullptr;
        return p;
    }
};

138. 复制带随机指针的链表 - 力扣(LeetCode)

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/

class Solution {
public:
    Node* copyRandomList(Node* head) {
        Node* h = new Node(0);
        Node* h1 = h;
        Node* hh = h;
        Node* t = head;
        Node* t1 = head;
        while(t != nullptr)
        {
            h->next = new Node(t->val);
            t = t->next;
            h = h->next;
        }
        while(t1 != nullptr)
        {
            if(t1->random != nullptr)
            {
                h1->next->random = find(head, hh -> next, t1->random);
            }
            t1 = t1->next;
            h1 = h1->next;
        }
        return hh->next;
    }
    Node* find(Node* h1, Node* h2, Node* t)
    {
        while(h1 != nullptr)
        {
            if(h1 == t)
            return h2;
            h1 = h1->next;
            h2 = h2->next;
        }
        return nullptr;
    }
};

160. 相交链表 - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *p1 = headA;
        ListNode *p2 = headB;
        if(!p1||!p2)return NULL;
        while(p1!=p2)
        {
            if(p1 == NULL)p1 = headB;
            else p1 = p1->next;
            if(p2 == NULL)p2 = headA;
            else p2 = p2->next;
        }
        return p2;
    }
};

430. 扁平化多级双向链表 - 力扣(LeetCode)

class Solution {
public:
    Node* flatten(Node* head) {
        for (Node* curr = head; curr != nullptr; curr = curr->next){
            // 如果遇到 curr->child 需要把一整层移上来
            if (curr->child){
                // 子链表一整层[start, end]
                Node* start = curr->child;
                Node* end = start;
                while (end->next != nullptr) end = end->next;
                // 把一整层带上来 (深度减去一层)
                end->next = curr->next;
                if (curr->next != nullptr)  curr->next->prev = end; 
                curr->next = start;
                start->prev = curr;
                curr->child = nullptr;
            }
        }
        return head; 
    }
};

725. 分隔链表 - 力扣(LeetCode)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    vector<ListNode*> splitListToParts(ListNode* head, int k) {
        ListNode* h = head;
        int cnt = 0;
        while(h != nullptr)
        {
            cnt ++;
            h = h->next;
        }
        //cnt = a(b + 1) + (k - a)(b) =  ab + a + kb - ab  = a + kb
        int a, b;
        b = cnt / k;
        a = cnt - k * b;
        vector<ListNode*> ans;
        for(int i = 1; i <= k; i ++ )//k组
        {
            if(i <= a)//a组b+1
            {
                ans.push_back(head);
                for(int j = 1; j <= b; j ++ )
                {
                    head = head->next;
                }
                ListNode* ne = head->next;
                head->next = nullptr;
                head = ne;
            }
            else
            {
                if(b == 0) 
                {
                    ans.push_back(nullptr);
                    continue;
                }
                ans.push_back(head);
                for(int j = 1; j <= b - 1; j ++ )
                {
                    head = head->next;
                }
                ListNode* ne = head->next;
                head->next = nullptr;
                head = ne;
            }
        } 
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值