题目描述:给定一个链表,看看是否有环。
解题思路:
方法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;
}
};
####################################
链表排序
链表的排序:合并排序,快速排序,插入排序
方法一: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,
Given1->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;
}
};