关闭

Leetcode__链表练习

标签: leetcode链表
244人阅读 评论(0) 收藏 举报
分类:

这里写链接内容题目是从Leetcode上面找的,这里创建链表使用头插法创建的

#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <stdio.h>
using namespace std;

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

}ListNode;

/**
 *  链表翻转
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {

        if (head == NULL)
            return NULL;      // 如果为空返回为空

        if (head->next == NULL)
            return head;
        ListNode * newHead = head;

        head = head->next;

        newHead->next = NULL;
        ListNode *tempHead;
        while (head!= NULL)
        {
            tempHead = head->next;
            head->next = newHead;
            newHead = head;
            head = tempHead;
        }

        return newHead;

    }
};


/**
 *  Remove Linked List Elements,Remove all 
 *  elements from a linked list of integers that have value val.
 */
class SolutionRemove {
public:
    ListNode* removeElements(ListNode* head, int val) {

        if (head == NULL)   // 如果是空直接返回
        {
            return NULL;
        }
        /**
         *  1.如果是移除第一个元素。2.移除最后的元素. 3.中间的元素
         */

        while (head!=NULL)
        {
            if (head->val == val)
            {
                head = head->next;
            }else
                break;
        }
        ListNode *res = head;
        ListNode *prior = head;
        while (head != NULL)
        {
            if (head->val == val)
            {
                prior->next = head->next;
                head = prior->next;
            }
            else
            {
                prior = head;
                head = head->next;
            }

            // 最后一个元素
            if (head == NULL&&prior->val == val)
            {
                prior = NULL;
                break;
            }
        }

        return res;

    }
};


/**
 * 创建一个长度为n的链表,
 */
ListNode *CreateLinkNode(int n)
{

    if (n <= 0)
        return NULL;
    ListNode *L;
    int i = 0;
    int value;
    ListNode *d=NULL;
    L = (ListNode *)malloc(sizeof(ListNode));
    L->next = NULL;
    scanf_s("%d", &value);
    L->val = value;
    d=L;
    while (i < n-1)
    {
        L = (ListNode *)malloc(sizeof(ListNode));
        scanf_s("%d", &value);
        L->val = value;
        L->next = d;
        d = L;
        i++;
    }

    return L;
}

/**
 *  打印链表
 */
void PrintListNode(ListNode *L)
{
    if (L == NULL)
    {
        printf("链表为空");
    }
    while (L!=NULL)
    {
        printf("%d",L->val);
        L = L->next;
    }
}

/**
 *  Remove Nth Node From End of List 
 *  For example,
 *  Given linked list: 1->2->3->4->5, and n = 2.
 *  After removing the second node from the end, the linked list becomes 1->2->3->5.
 */
class Solution9 {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {

        if (head == NULL)
            return NULL;

        if (head->next == NULL)
        {
            return NULL;
        }
        ListNode *res = head;
        // 删除倒数第二个值,用两个指针就行了
        ListNode *h1 = head;
        ListNode *prior=head;
        int i = 0;
        while (i < n-1)
        {
            head = head->next;
            i++;
        }
        if (head->next == NULL)  // 表示n是链表的长度
        {
            return res->next;
        }
        while (head->next!=NULL)
        {
            head = head->next;
            prior = h1;
            h1 = h1->next;
            if (h1->next == NULL)  // 表示n=1
            {
                prior->next = NULL;
                return res;
            }
        }
        prior->next = h1->next;
        return res;
    }
};

/**
 *  Given a sorted linked list, delete all duplicates such that each element appear only once.
 *  For example,
 *  Given 1->1->2, return 1->2.
 *  Given 1->1->2->3->3, return 1->2->3.
 */
class Solution83 {
public:
    ListNode* deleteDuplicates(ListNode* head) {

        if (head == NULL)
            return NULL;
        ListNode *h1 = head;
        ListNode *h2 = head->next;

        while (h2!=NULL)
        {
            if (h1->val == h2->val)
            {
                h1->next = h2->next;
                h2 = h2->next;
            }
            else
            {
                h1 = h1->next;
                h2 = h2->next;
            }
        }

        return head;
    }
};

/**
 *  Remove Duplicates from Sorted List II 
 *  Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
 *  For example,
 *  Given 1->2->3->3->4->4->5, return 1->2->5.
 *  Given 1->1->1->2->3, return 2->3.
 */
class Solution82 {
public:
    ListNode* deleteDuplicates(ListNode* head) {

        if (head == NULL)
            return NULL;
        bool flag = true;

        while (head)   // 处理第一个值是重复的情况
        {
            bool  b = true;
            if (head->next == NULL)
            {
                return head;
            }
            while (head->val == head->next->val)
            {
                b = false;
                head = head->next;
                if (head->next == NULL)
                    return NULL;
            } 
            if (!b)
            {
                head = head->next;
                b = true;
            }
            else
            {
                break;
            }
        }
        ListNode *h1 = head;
        ListNode *prior = head; //  保存前驱节点
        while (head)
        {
            ListNode *node = head->next;
            if (node == NULL)
                return h1;
            while (head->val == node->val)
            {
                flag = false;
                head->next = node->next;
                node = node->next;
                if (node == NULL)      // 处理最后一个值
                {
                    prior->next = NULL;
                    return h1;
                }

            }
            if (flag)
            {
                prior = head;
                head = head->next;
            }else
            {
                prior->next = head->next;
                head = head->next;
                flag = true;
            }
        }

        return h1;
    }
};

/**
 *  Reverse a linked list from position m to n. Do it in-place and in one-pass.
 *  For example:
 *  Given 1->2->3->4->5->NULL, m = 2 and n = 4,
 *  return 1->4->3->2->5->NULL.
 *  Note:
 *  Given m, n satisfy the following condition:
 *  1 ≤ m ≤ n ≤ length of list.
 */
/************************************************************************/
/* 解题思路:
 * 1.如果m和n的值相等,无需处理。head==NULL 直接返回head
 * 2.如果m==1表示头部要特殊处理
 * 3.如果n==leng of list 也要特殊考虑
 */
/************************************************************************/
class Solution92 {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {

        if (m == n)
            return head;
        ListNode *priorM = head;
        ListNode *nodeM = head;
        nodeM = head;
        int i = 1;
        while (i < m)
        {
            priorM = nodeM;
            nodeM = nodeM->next;
            i++;
        }
        // 插入
        ListNode *tempNode = nodeM->next;
        ListNode *l;
        if (m == 1)
        {
            ListNode *h1 = head->next;
            ListNode *h2 = h1->next;
            while (i<n)
            {

                h1->next = head;
                priorM->next = h2;
                head = h1;
                h1 = h2;
                if (h2 == NULL)
                    return head;
                h2 = h2->next;
                i++;
            }

        }
        ListNode *dd = nodeM;
        while (i<n)
        {
            l = tempNode->next;

            tempNode->next = nodeM;
            priorM->next = tempNode;
            if (l == NULL)
            {
                dd->next = NULL;
                break;
            }
            dd->next = l;
            nodeM=tempNode ;

            tempNode = l;
            i++;
        }
        return head;
    }
};


/**
 *  Merge two sorted linked lists and return it as a new list. 
 *  The new list should be made by splicing together the nodes of the first two lists.
 *  题目意思,没有想到重新启动一个链表啊 SB
 */
class Solution21 {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *root, *p;
        root = new ListNode(-1);
        p = root;
        while (1)
        {
            if (l1 == NULL){ p->next = l2; break; }
            if (l2 == NULL){ p->next = l1; break; }
            if (l1->val < l2->val)
            {
                p->next = l1;
                l1 = l1->next;
            }
            else
            {
                p->next = l2;
                l2 = l2->next;
            }
            p = p->next;
        }
        ListNode *temp = root->next;
        delete(root);
        return temp;
    }
};
int main()
{
    int length = 4;
    ListNode *l = CreateLinkNode(length);
    PrintListNode(l);
    printf("\n");

    //////////////////////////////////////////////////////////////////////////
//  Solution *sol = new Solution();
//  PrintListNode(sol->reverseList(l));

    //////////////////////////////////////////////////////////////////////////
//  SolutionRemove *solRemove = new SolutionRemove();
//  PrintListNode(solRemove->removeElements(l, 3));

    //////////////////////////////////////////////////////////////////////////
//  Solution9 *sol9 = new Solution9;
//  PrintListNode(sol9->removeNthFromEnd(l, 3));


    //////////////////////////////////////////////////////////////////////////
//  Solution83 *sol83 = new Solution83;
//  PrintListNode(sol83->deleteDuplicates(l));

    //////////////////////////////////////////////////////////////////////////
//    Solution82 *sol82 = new Solution82;
//    PrintListNode(sol82->deleteDuplicates(l));

    //////////////////////////////////////////////////////////////////////////
//  Solution92 *sol92 = new Solution92;
//  PrintListNode(sol92->reverseBetween(l,2,5));

    //////////////////////////////////////////////////////////////////////////
    //ListNode *l2 = CreateLinkNode(length);
    //PrintListNode(l);
    //printf("\n");

    //Solution21 *sol21 = new Solution21;
    //PrintListNode(sol21->mergeTwoLists(l, l2));

    system("pause");
    return 0;
}

这里的链表都是不带头结点的链表,看别人使用带头节点的链表结构,处理可能比较简单。带头结点的链表在头部删除和插入可能操作比较统一,不用考虑那么多的情况。参考程序
感觉还是人家写的比较简单。我要考虑的情况太多了,如Remove Duplicates from Sorted List II。
http://blog.csdn.net/chencheng126/article/details/39029889

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:12210次
    • 积分:348
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:0篇
    • 译文:3篇
    • 评论:4条
    文章分类
    最新评论