算法与数据结构之链表

一.翻转链表

在翻转专题中提到了,提供地址
文章地址:http://www.cnblogs.com/vhyz/p/7241743.html

二.合并排序链表

21. Merge Two Sorted Lists

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、

两个排序链表合并,并且合并后还得是已排序的

利用递归的方式,贴上代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1==nullptr )
            return l2;
        if(l2==nullptr)
            return l1;
        if(l1->val<l2->val)
        {
            l1->next = mergeTwoLists(l1->next,l2);
            return l1;
        }
         else{
                l2->next = mergeTwoLists(l1,l2->next);
                return l2;
            }
        
    }
};

该方法特别好,先比较大小,随后将比较好大小的链表与第二个链表继续递归

另一种思路是利用中间临时变量p来循环,思路与递归差不多,贴上代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* head = new ListNode(-1);
        ListNode* p = head;
        while (l1 != NULL || l2 != NULL)
        {
            int val1 = l1==NULL ? INT_MAX:l1->val;
            int val2 = l2==NULL ? INT_MAX:l2->val;
            if (val1 <= val2)
            {
                p->next = l1;
                l1 = l1->next;
            }
            else
            {
                p->next = l2;
                l2 = l2->next;
            }
            p = p->next;
        }
        p = head->next;
        delete head;
        return p;
 }
};

值得注意的一点是,提前用head保存了p的原来位置是很明智的

三.删除排序链表中的重复元素

83. Remove Duplicates from Sorted List

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode* temp = nullptr;
        if(head == nullptr)
            return nullptr;
        ListNode* result = head;
        while(head->next)
        {
            temp = head->next;
            if(head->val == temp->val)
            {
                head->next = temp->next;
            }
            else
            {
                head = temp;
            }
        }
        return result;
    }
};

四.删除链表中指定值的节点

203. Remove Linked List Elements

Remove all elements from a linked list of integers that have value val.
Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5

递归算法

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

先遍历各个节点直到结尾,然后返回,如果该节点符合要求,那么返回该节点的next指针即下一个节点

循环算法

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode *pseudo_head = new ListNode(0);
        pseudo_head->next = head;
        ListNode *cur = pseudo_head;
        while(cur){
            if(cur->next && cur->next->val == val)   cur->next = cur->next->next;
            else    cur = cur->next;
        }
        return pseudo_head->next;
    }
};

创建新节点,该节点指向head,然后再创建节点等于该新节点,将节点cur一直指向下一节点

cur->next = cur->next->next;

注意上面这一行,这一行一直成为我算法的问题,值得学习。

指向节点指针的指针法

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
    ListNode** list;
        list = &head;
        while(*list != NULL)
        {
            if((*list)->val == val)
            {
              *list = (*list)->next;
            }
            else
            {
                list = &((*list) ->next);
            }
        }
        return head;
    }
};

五.判断链表是否回文

234. Palindrome Linked List

翻转整个链表再判断

因为链表只有一个,所以要复制链表才能继续,赋值链表要注意空节点

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head == nullptr)
            return true;
        ListNode * p = nullptr;
        ListNode * q = new ListNode (head->val);
        ListNode * t = q;
        while(head)
        {
            ListNode* next = head->next;
            head->next = p;
            p = head;
            head = next;
            if(head){
                 ListNode* temp = new ListNode(head->val);
                 t->next = temp;
                t = t->next;
            }
        }
        while(p)
        {
            if(p->val != q->val)
                return false;
            p = p->next;
            q = q->next;
        }
        return true;
    }
};

翻转链表与复制链表同时进行

翻转一半链表做判断

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head == nullptr||head->next == nullptr )
            return true;
        ListNode * fast = head;
        ListNode * slow = head;
        while(fast->next !=nullptr && fast->next->next != nullptr)
        {
            slow = slow->next;
            fast = fast->next->next;
        }
        slow = re(slow->next);
        while(slow)
        {
            if(slow->val != head->val)
                return false;
            slow = slow->next;
            head = head->next;
        }
        return true;
    }
    ListNode * re(ListNode * slow)
    {
        ListNode * p =nullptr;
        ListNode * next =nullptr;
        while(slow)
        {
            next = slow->next;
            slow->next = p;
            p = slow;
            slow = next;
        }
        return p;
    }
};

特别注意空节点没有next指针,否则报错!

递归 全局变量法

class Solution {
public:
    ListNode * temp;
    bool isPalindrome(ListNode* head) {
        temp = head;
        return check (head);
    }
    bool check(ListNode * p)
    {
        if(p == nullptr)
            return true;
        bool result = check(p->next) && (p->val == temp->val);
        temp = temp->next;
        return result;
    }
};

利用temp的延迟性来打到算法目的

六.给两个已排序的单向链表合成为一个

21. Merge Two Sorted Lists

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

递归算法

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1==nullptr )
            return l2;
        if(l2==nullptr)
            return l1;
        if(l1->val<l2->val)
        {
            l1->next = mergeTwoLists(l1->next,l2);
            return l1;
        }
         else{
                l2->next = mergeTwoLists(l1,l2->next);
                return l2;
            }
        
    }
};

循环算法

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode * ans = new ListNode (0);
        ListNode * q = ans;
        while(l1&&l2)
        {
            if(l1->val<l2->val)
            {
                q->next = l1;
                l1 = l1->next;
            }
            else{
                q->next = l2;
                l2 = l2->next;
            }
            q=q->next;
        }
        q->next = l1?l1:l2;
        return ans->next;
    }
};
posted @ 2017-07-26 22:31  vhyz  阅读(226)  评论(0编辑  收藏  举报