leetcode之链表

141. Linked List Cycle

题目描述:给定一个链表,看看是否有环。

解题思路:

方法1:hash存储每一个节点的地址,看看是否有重复。

缺点:消耗额外的空间。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) 
    {
        unordered_map<ListNode *,bool> hash;
        if(head==NULL||head->next==NULL)
        {
            return false;
        }
        while(head!=NULL)
        {
            if(hash[head]==true)
            {
                return true;
            }
            hash[head]=true;
            head=head->next;
        }
        return false;
    }
};
思路2:快慢指针,两个指针,一个每次走一步,一个每次走两步,如果能够相遇,则证明有环。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) 
    {
        if(head==NULL||head->next==NULL)
        {
            return false;
        }
        ListNode * slow=head;
        ListNode * fast=head;
        while(slow&&fast&&fast->next)
        {
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast)
            {
                return true;
            }
        }
        return false;
        
    }
};

142. Linked List Cycle II

题目描述:给定一个链表,如果是有环的,返回环的起始位置,如果没环,返回空;

解题思路:先判断有没有环,如果有环,再判断环的位置。判断环的位置可以手动推一下;

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) 
    {
        if(head==NULL||head->next==NULL)
        {
            return NULL;
        }
        ListNode * first=head;
        ListNode * second=head;
        while(first&&second&&second->next)
        {
            first=first->next;
            second=second->next->next;
            if(first==second)
            {
                break;
            }
        }
        if(first==NULL||second==NULL||second->next==NULL)
        {
            return NULL;
        }
        first=head;
        while(first!=second)
        {
            first=first->next;
            second=second->next;
        }
        return first;
        
    }
};
237. Delete Node in a Linked List
题目描述:删除链表中的一个节点;这个题目很SB,没啥意思

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) 
    {
        *node=*(node->next);
        
    }
};
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 * node=head;
    	while(head !=NULL)
    	{
    		while(head->next!=NULL&&head->next->val==head->val)
    		{
    			head->next=head->next->next;
    		}
    		head=head->next;
    	}
    	return node;
        
    }
};
160. Intersection of Two Linked Lists
题目描述:求两个链表的交集

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3
解题思路:在网上看到一个特别牛逼解题思路,从头开始遍历,如果一个到结尾了,则继续遍历另一个链表的开始处。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) 
    {
        if(headA==NULL||headB==NULL)
        {
            return NULL;
        }
        ListNode * first=headA;
        ListNode * second=headB;
        while(first&&second&&first!=second)
        {
            first=first->next;
            second=second->next;
            if(first==second)
            {
                return first;
            }
            if(first==NULL)
            {
                first=headB;
            }
            if(second==NULL)
            {
                second=headA;
            }
        }
        return first;
    }
};
203. Remove Linked List Elements
题目描述:删除链表中的给定的元素。

Example
Given:  1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6,  val  = 6
Return:  1 --> 2 --> 3 --> 4 --> 5

解题思路:删除该节点,所以我们必须得到该节点前面的节点。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) 
    {
        if(head==NULL||head->next==NULL&&head->val==val)
        {
            return NULL;
        }
        ListNode * ret=new ListNode(-1);
        ret->next=head;
        head=ret;
        while(ret->next)
        {
            if(ret->next->val==val)
            {
                ret->next=ret->next->next;
            }
            else
            {
               ret=ret->next; 
            }
        }
        return head->next;
        
        
    }
};
206. Reverse Linked List
题目描述:反转链表

解题思路:记录前一个节点,后一个节点,当前节点即可;

代码:

/**
 * 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 * prev=NULL;
        ListNode * cur=head;
        ListNode * next=NULL;
        while(cur)
        {
            next=cur->next;
            cur->next=prev;
            prev=cur;
            cur=next;            
        }
        return prev;
        
    }
};
234. Palindrome Linked List
题目描述:判断一个链表是不是回文链表

解题思路:

(1)旋转该链表,判断是不是相等。

(2)将链表的前半部分入栈,然后跟后半段进行比较;在这里一定要判断奇数还是偶数个元素。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) 
    {
        if(head==NULL||head->next==NULL)
        {
            return true;
        }
        ListNode * first=head;
        ListNode * second=head;
        stack<int> S;
        S.push(first->val);
        while(second->next&&second->next->next)
        {
            second=second->next->next;
            first=first->next;
            S.push(first->val);
        }
        if(second->next==NULL)
        {
            S.pop();
        }
        while(first->next)
        {
            first=first->next;
            if(first->val!=S.top())
            {
                return false;
            }
            S.pop();
        }
        return true;
        
    }
};

21 Merge Two Sorted 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 == NULL) return l2;
    if (l2 == NULL) return l1;
    
    ListNode *ret = NULL;
    
    if (l1->val < l2->val)
    {
        ret = l1;
        ret->next = mergeTwoLists(l1->next, l2);
    }
    else
    {
        ret = l2;
        ret->next = mergeTwoLists(l1, l2->next);
    }
    
    return ret;
        
    }
};
61. Rotate List
题目描述:给定一个链表,向右移动K的位置。

解题思路:没啥想的,写就可以。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) 
    {
        ListNode * newNode=head;
        if(head==NULL||head->next==NULL||k==0)
        {
            return head;
        }
        int n=1;
        while(head->next)
        {
            n++;
            head=head->next;
        }
        head->next=newNode;
        int m=n-k%n;
        for(int i=1;i<m;i++)
        {
            newNode=newNode->next;
        }
        head=newNode->next;
        newNode->next=NULL;
        return head;
    }
};
####################################

链表排序

148. Sort List


链表的排序:合并排序,快速排序,插入排序

方法一:mergeSort

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(head==NULL||head->next==NULL)
        {
            return head;
        }
        ListNode * dummy=new ListNode(-1);
        ListNode * head1=dummy;
        ListNode * head2=dummy;
        dummy->next=head;
        while(head2&&head2->next)
        {
            head1=head1->next;
            head2=head2->next->next;
        }
        head2=head1->next;
        head1->next=NULL;
        head1=head;
        return merge(sortList(head1),sortList(head2));
    }
    ListNode* merge(ListNode *l1, ListNode *l2)
    {
        if(l1==NULL)
        {
            return l2;
        }
        if(l2==NULL)
        {
            return l1;
        }
        if(l1->val<l2->val)
        {
            l1->next=merge(l1->next,l2);
            return l1;
        }
        else
        {
            l2->next=merge(l1,l2->next);
            return l2;
        }
    }

};

方法2:quick sort

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void sortListHelper(ListNode* head, ListNode* tail) {
    	if (head -> next == tail) 
            return;
    	/* Partition the list. */
    	ListNode* pre = head;
    	ListNode* cur = head -> next; 
    	ListNode* pivot = cur;
    	while (cur -> next && cur -> next != tail) 
        {		
    		if (pivot -> val > cur -> next -> val) 
            {
    			ListNode* temp = pre -> next;
    			pre -> next = cur -> next;
    			cur -> next = cur -> next -> next;
    			pre -> next -> next = temp;
    		}
    		else 
                cur = cur -> next;
    	}
    	sortListHelper(head, pivot);
    	/* Here is the trick. */
    	while (pivot -> next != tail && pivot -> next -> val == pivot -> val)
    	    pivot = pivot -> next;
    	if (pivot -> next != tail) 
            sortListHelper(pivot, tail);
    } 
    
    ListNode* sortList(ListNode* head) 
    {
    	ListNode* new_head = new ListNode(0);
    	new_head -> next = head;
    	sortListHelper(new_head, NULL);
    	return new_head -> next;
    }
};

方法3:insert sort

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* insertionSortList(ListNode* head) 
    {
        ListNode * dummy=new ListNode(-1);
        while(head)
        {
            ListNode * temp=dummy;
            while(temp->next&&temp->next->val<head->val)
            {
                temp=temp->next;
            }
            ListNode * Next=head->next;
            head->next=temp->next;
            temp->next=head;
            head=Next;
        }
        return dummy->next;
    }
};

143. Reorder List

题目描述:重新排序链表 {1,2,3,4}, reorder it to {1,4,2,3}.

解题思路:

思路一:反转链表,然后依次添加

思路二:遍历该数组,存入数组,然后重新排序

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void reorderList(ListNode* head) {
        if (head==NULL||head->next==NULL)
        {
        	/* code */
        	return;
        }
        std::vector<ListNode *> nodes;
        ListNode* iter = head;
        while(iter)
        {
        	nodes.push_back(iter);
        	iter=iter->next;
        }
        int len=nodes.size();
        int left=0;
        int right=len-1;
        while(left<right)
        {
        	nodes[left]->next=nodes[right];
        	left++;
        	nodes[right]->next=nodes[left];
        	right--;
        }
        nodes[left]->next=NULL;
    }
};
92. Reverse Linked List II
题目描述:反转区间链表。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) 
    {
        ListNode * dummy=new ListNode(-1);
        dummy->next=head;
        ListNode * prev=dummy;
        ListNode * next=NULL;
        for(int i=1;i<m;i++)
        {
            prev=prev->next;
        }
        ListNode * cur=prev->next;
        for(int i=m;i<n;i++)
        {
            ListNode* move = cur -> next; 
            cur -> next = move -> next;
            move -> next = prev -> next;
            prev -> next = move;
        }
        return dummy->next;
        
        
    }
};
86. Partition List
题目描述:给定一个链表,然后给定一个数值,大于等于该数值的节点都在小于该节点的后面。

解题思路:设两个节点,一个存小于的,一个存大于等于的。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* partition(ListNode* head, int x) 
    {
        ListNode * first =new ListNode(-1);
        ListNode * second =new ListNode(-1);
        ListNode * node1=first;
        ListNode * node2=second;
        while(head)
        {
            if(head->val<x)
            {
                first=first->next=head;
            }
            else
            {
                second=second->next=head;
            }
            head=head->next;
        }
        first->next=node2->next;
        second->next=NULL;
        return node1->next;
        
    }
};
82. Remove Duplicates from Sorted List II

题目描述:删除重复的节点。

For example,

Given  1->2->3->3->4->4->5 , return  1->2->5 .
Given  1->1->1->2->3 , return  2->3 .

解题思路:从开始处进行遍历,如果第二个节点的值不与第一个节点的值相同,可以递归的调用函数。否则,找到第一个与开始节点值不同的节点,并调用函数,返回该节点的值。

代码如下:

/**
 * 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) 
    {
        if(head==NULL||head->next==NULL)
        {
            return head;
        }
        int val=head->val;
        if(head->next->val!=val)
        {
            head->next=deleteDuplicates(head->next);
            return head;
        }
        else
        {
            while(head->next&&head->next->val==val)
            {
                head->next=head->next->next;
            }
            return deleteDuplicates(head->next);
        }
        
        
    }
};
328. Odd Even Linked List
题目描述:奇偶进行对换,奇数的节点后面接偶数的节点。

Example:
Given  1->2->3->4->5->NULL ,
return  1->3->5->2->4->NULL .

解题思路:

code:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* oddEvenList(ListNode* head)
    {
        if(head==NULL||head->next==NULL)
        {
            return head;
        }
        ListNode * odd=head;
        ListNode * even=head->next;
        ListNode * even_bak=head->next;
        while(odd->next&&odd->next->next)
        {
            odd=odd->next=even->next;
            even=even->next=odd->next;
        }
        odd->next=even_bak;
        return head;
    }
};
109. Convert Sorted List to Binary Search Tree
题目描述:将排好序的链表转换成平衡的二叉搜索树。

解题思路:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *sortedListToBST(ListNode *head) 
    {
        if (head==NULL) 
        {
            return NULL;
        }
        if (head->next==NULL)
        {
            return new TreeNode(head->val);
        }
        ListNode *slow = head;
        ListNode *fast = head;
        ListNode *last = slow;
        while (fast->next && fast->next->next) 
        {
            last = slow;
            slow = slow->next;
            fast = fast->next->next;
        }
        fast = slow->next;
        last->next = NULL;
        TreeNode *cur = new TreeNode(slow->val);
        if (head != slow) 
            cur->left = sortedListToBST(head);
        cur->right = sortedListToBST(fast);
        return cur;
    }
};

25. Reverse Nodes in k-Group

题目描述:

For example,
Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5

解题思路:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverse(ListNode* first, ListNode* last)
    {
        ListNode * prev=last;
        while(first!=last)
        {
            ListNode * temp=first->next;
            first->next=prev;
            prev=first;
            first=temp;
        }
        return prev;
    }
    ListNode* reverseKGroup(ListNode* head, int k) 
    {
        auto node=head;
        for (int i=0; i < k; ++i)
        {
            if ( ! node  )
                return head; 
            node = node->next;
        }

        auto new_head = reverse( head, node);
        head->next = reverseKGroup( node, k);
        return new_head;
        
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值