我要好offer之 链表大总结

单链表是一种递归结构,可以将单链表看作特殊的二叉树(我把它叫做一叉树)

单链表的定义:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

1. O(1)时间删除结点

ListNode* DeleteNode(ListNode* pHead, ListNode* deletedNode) {
    assert(pHead != NULL && deletedNode != NULL);
    ListNode newHead(-1);
    newHead.next = pHead;
    if (pHead == deletedNode) {
        newHead->next = pHead->next;
        delete deletedNode;
        deketedNode = NULL;
        return newHead.next;
    } else {
        if (deleteNode->next == NULL) {
            ListNode* cur = pHead;
            while (cur->next != deleteNode) {
                cur = cur->next;
            }
            cur->next = NULL;
            delete deletedNode;
            deletedNode = NULL;
            return newHead.next;
        } else {
            ListNode* nextNode = deletedNode->next;
            deletedNode->val = nextNode->val;
            deletedNode->next = nextNode->next;
            delete nextNode;
            nextNode = NULL;
            return newHead.next;
        }
    }
}

2. 单链表反转

ListNode* ReverseList(ListNode* pHead) {
    if (pHead == NULL || pHead->next == NULL) {
        return pHead;
    }
    ListNode* tail = pHead;
    ListNode* cur = pHead->next;
    while (cur != NULL) {
        ListNode* nextNode = cur->next;
        cur->next = pHead;
        pHead = cur;
        cur = nextNode;
    }
    tail->next = NULL;
    return pHead;
}

3. 单链表倒数第k个结点

ListNode* KthNode(ListNode* pHead, int k) {
    assert(pHead != NULL && k > 0);
    ListNode* first = pHead;
    ListNode* second = pHead;
    while (first != NULL && k > 0) {
        first = first->next;
        --k;
    }
    if (first == NULL) {
        if (k == 0) {
            return pHead;
        } else {
            return NULL;
        }
    }
    while (first != NULL) {
        first = first->next;
        second = second->next;
    }
    return second;
}

4. 单链表反转部分区间

5. 单链表快速排序的一趟划分

6. 单链表去掉重复元素

7. 单链表旋转

8. 单链表成对交换节点

9. 有序单链表归并排序

10. 单链表加法运算

11. 单链表是否存在环,环的位置

12. 两个单链表的第一个公共结点

我要好offer之 链表大总结

时间: 2024-10-08 13:08:03

我要好offer之 链表大总结的相关文章

我要好offer之 二叉树大总结

一. 二叉树定义:二叉树具有天然的递归特性,凡是二叉树相关题,首先应该联想到递归 struct BinTreeNode { BinTreeNode* left; BinTreeNode* right; int val; BinTreeNode(int value) : left(nullptr), right(nullptr), val(value) { } }; 二. 二叉树遍历 详见笔者博文:二叉树遍历大总结 1 #include <iostream> 2 #include <vec

我要好offer之 搜索算法大总结

1. 二分搜索 详见笔者博文:二分搜索的那些事儿,非常全面 2. 矩阵二分搜索 (1) 矩阵每行递增,且下一行第一个元素大于上一个最后一个元素 (2) 矩阵每行递增,且每列也递增 3. DFS 深度优先搜索 适用场景: (1) 输入数据:如果是 递归数据结构(如单链表.二叉树),则一定可以使用DFS (2) 求解目标:必须走到最深处(例如二叉树,必须走到叶子节点)才能得到一个解,这种情况一般适合用DFS 思考步骤: (1) DFS最常见的3个问题:求可行解的总数.求任一个可行解.求所有可行解 (

我要好offer之 C++大总结

0. Google C++编程规范 英文版:http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml 中文版:http://zh-google-styleguide.readthedocs.org/en/latest/google-cpp-styleguide/contents/ 1. C++函数的林林总总 2. Effective C++学习笔记 (1) 习惯c++,const特性 (2) 构造.析构.赋值.copy and

我要好offer之 排序算法大总结

1. 插入排序 (1) 直接插入排序 void StraightInsertionSort(std::vector<int>& num) { if (num.size() == 0 || num.size() == 1) return; for (int i = 1; i < num.size(); ++i) { int tmp = num.at(i); int j = i - 1; for (; j >= 0 && num.at(j) > tmp;

我要好offer之 str/mem系列手写代码

1. str*系列手写代码 a. 一定要注意末尾'\0'的处理,切记切记 b. 一定要对输入做有效性判断,多用断言就是了 int Strlen(const char* str) { assert(str != NULL); const char* tmp = str; while (*tmp != '\0') { ++tmp; } return tmp - str; } char* Strcpy(char* dst, const char* src) { assert(dst != NULL &

【剑指offer】链表倒数第k个节点

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25662121 在Cracking the Code Interview上做过了一次,这次在九度OJ上测试,AC. 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(hint: 请务必使用链表.) 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为两个整数n和k(0<=n<=1000, 0<=k<=1000):n代表将要输入的链表元素的

单链表大整数加法

单链表大整数加法,节点是char型. First     List:   head->1->8->9 Second List:   head->9->8->1 Result  List:    head->1->1->7->0 实现了单链表(单链表类模板),现在使用单链表实现大整数加法 1 #include "stdafx.h" 2 #include "SingleList.h" 3 #include &l

剑指offer (5) 链表插入删除

我们在操作链表的时候,必须注意以下事项: 1. 链表指针为NULL的情况 2. 插入删除涉及到 链表第一个节点时,需要修改 链表的第一个节点: a. 因为 c语言都是传值的,如果需要修改一个变量,就必须通过 指向该变量的指针(即该变量的地址) 例如:例如 修改 int a,则输入参数必须是 int* a, 修改a 则是: *a = b; (b为int) 我们需要修改一个指针时,就必须通过 该指针的地址,也就是 指向该指针的指针,即二级指针 例如  修改 int* a, 则输入参数必须是 int*

剑指offer之链表

//剑指offer 之 链表 //面试题6 从尾到头打印链表 /***************************************************************************************** 问题描述: 输入一个链表的头节点,从尾到头反过来打印出每个节点的值 链表节点定义如下: struct ListNode{ int m_nValue; ListNode* m_pNext; }; *******************************