链表基本操作题

1. 链表反转,

// 3指针,原地反转

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = NULL, *cur = head, *nxt = NULL;
        while(cur)
        {
            nxt = cur->next;
            cur->next = pre;
            pre = cur;
            cur = nxt;
        }
        return pre;
    }
};

2. 翻转链表m到n的结点,要求一次遍历完成(leetcode92)

Node* reverseBetween(Node* head, int m, int n)
{
    Node h(0);
    h.next = head;  //设置一个头节点,处理m=1的情况
    Node* p = &h;
    Node* tail;
    for(int i = 1; i <= n; i++)
        if(i < m) // p指向第n-1个节点位置
            p = p->next;
        else if(i == m) // tail指向第第n个节点,这个节点反转后处在反转部分的最后一个
            tail = p->next;
        else { //每次将tail后面一个节点拿出来,放在p后面,即头插法
            Node* item = tail->next;
            tail->next = tail->next->next;
            item->next = p->next;
            p->next = item;
        }
    return h.next;
}

3. 两个链表相加(leetcode2)

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode vhead(0), *p = &vhead;
        int carry = 0;
        while(l1 || l2 || carry)
        {
            int tmp = carry;
            if(l1 != NULL)  tmp += l1->val;
            if(l2 != NULL)  tmp += l2->val;
            carry = tmp / 10;
            tmp %= 10;
            
            ListNode* next = l1 ? l1 : l2;  // 交错
            if(next == NULL)  next = new ListNode(tmp); // 进位
            next->val = tmp;

            p->next = next;
            p = p->next;

            l1 = l1 ? l1->next : NULL;
            l2 = l2 ? l2->next : NULL;
        }
        return vhead.next;
    }

4. 求链表中的倒数第K个节点

一种直观的思路是先遍历链表得到链表的长度,然后第二次遍历就能找到第k个节点,但是需要进行两次遍历,不是好的方法;
这里使用两个指针实现一次遍历,第一个指针先走k-1步,第二个指针一直不动;然后两个指针同时移动,知道第一个指针遍历完成。因为两个指针间隔为k-1,所以第二个指针指向的节点即为倒数第k个节点。
————————————————
版权声明:本文为CSDN博主「大树先生的博客」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Koala_Tree/article/details/79011152

    ListNode* getKthFromEnd(ListNode* head, int k) {
        ListNode* p1 = head, *p2 = head;
        for(int i = 0;i < k-1;i++)  p2 = p2->next;
        while(p2->next)
        {
            p1 = p1->next;
            p2 = p2->next;
        }
        return p1;
    }

5. 判断两个链表是否相交 leetcode160

思路一:最简单的先遍历一遍得到lenA, lenB,让长的先走掉差,再 同步走

思路二:先两者同时走,先到null的去另一条,两者再走掉差,此时长的也到null了改去另一条,此时剩下的长度相同。

思路三:将其中一条首尾相连,转化成了找环的入口

// 思路二    
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    ListNode* pa = headA, *pb = headB;
    while(pa != pb)
    {
        pa = pa == NULL ? headB : pa->next;
        pb = pb == NULL ? headA : pb->next;
    }   
    return pa;
}

5. 头插法和输出

#include<bits/stdc++.h>
using namespace std;

typedef struct Node
{
    int val;
    Node* next;
    Node(int _val=0):val(_val), next(NULL){}
}Node;

// 构建链表
// 头插法
Node* insert(Node* head, int val)
{
     Node* p = (Node*)malloc(sizeof(Node));
     p->val = val;
     p->next = head;
     head = p;
     return head;
}

// 遍历链表
void print(Node* head)
{
    Node* p = head;
    while(p)
    {
        printf("%d ", p->val);
        p = p->next;
    }
}

// 逆序输出
void print_r(Node* head)
{
    if(head == NULL)  return;
    if(head->next == NULL)
    {
        printf("%d ", head->val);
        return;
    }
    print_r(head->next);
    printf("%d ", head->val);
}

// 求倒数第k个节点
void Kth_r(Node * head, int k)
{
    Node *p = head, *p2 = head;
    for(int i = 0;i < k;i++) p = p->next;
    printf("p: %d\n", p->val);
    while(p != NULL)
    {
        p = p->next;
        p2 = p2->next;
    }
    printf("p2: %d\n", p2->val);
}

int a[] = {1, 2, 3, 4, 5}, n = 5;

int main()
{
    Node* head = (Node*)malloc(sizeof(Node));
    head->next = NULL, head->val = a[0];
    int i = 1;
    while(i < n)
    {
        head = insert(head, a[i]);
        i++;
    }
    print_r(head);
    printf("\n");

    Kth_r(head, 2);

    return 0;
}

 

posted @ 2020-03-07 14:43  Rogn  阅读(72)  评论(0编辑  收藏