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个节点。

————————————————



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; }




个性签名:时间会解决一切