链表的一些oj题
1.删除链表中等于给定值 val 的所有结点。 OJ链接
思路:从头遍历一遍链表,如果该节点的val和要删除的val相同的话删除该节点,反之则走过该咋点判断下一个节点
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode * pre = NULL;
struct ListNode *cur = head;
struct ListNode *phead = head;
while(cur != NULL)
{
if(cur->val == val)
{
if(cur == phead)
{
struct ListNode* nextnode = cur->next;
free(cur);
phead = nextnode;
cur = phead;
}
else
{
struct ListNode* nextnode = cur->next;
free(cur);
pre->next = nextnode;
cur = nextnode;
}
}
else
{
pre = cur;
cur = cur->next;
}
}
return phead;
}
2. 反转一个单链表。OJ链接
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* cur = head;
struct ListNode* phead = head;
while(cur)
{
if(cur == head)
{
cur = cur->next;
phead->next = NULL;
}
else
{
struct ListNode* nextnode = phead;
phead = cur;
cur = cur->next;
phead->next = nextnode;
}
}
return phead;
}
3. 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。OJ链接
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* fast = head,*slow = head;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
4. 输入一个链表,输出该链表中倒数第k个结点 OJ链接
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
struct ListNode* fast = pListHead,*slow = pListHead;
//fast先走K步
while(k--)
{
if(fast == NULL)//防止fast越界
{
return NULL;
}
fast = fast->next;
}
while(fast != NULL)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
5. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结OJ链接
点之前
ListNode* partition(ListNode* pHead, int x) {
// write code here
ListNode* LessHead,*LessTail;
ListNode* GreaterHead,*GreaterTail;
ListNode* cur = pHead;
LessHead = (ListNode*)malloc(sizeof(ListNode));
LessTail = LessHead;
GreaterHead = (ListNode*)malloc(sizeof(ListNode));
GreaterTail = GreaterHead;
while(cur)
{
if(cur->val < x)
{
LessTail->next = cur;
LessTail = cur;
cur = cur->next;
}
else
{
GreaterTail->next = cur;
GreaterTail = cur;
cur = cur->next;
}
}
LessTail->next = GreaterHead->next;
GreaterTail->next = NULL;
pHead = LessHead->next;
free(LessHead);
free(GreaterHead);
return pHead;
}
6. 链表的回文结构。OJ链接
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
ListNode* FindMid(ListNode* A)
{
struct ListNode* fast = A,*slow = A;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
ListNode* RollList(ListNode* Mid)
{
ListNode* phead = NULL;
while(Mid)
{
ListNode* next = Mid->next;
Mid->next = phead;
phead = Mid;
Mid = next;
}
return phead;
}
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
//找到中间节点
ListNode* Mid = FindMid(A);
//反转mid之后的节点得到新的链表
ListNode* phead = RollList(Mid);
//比较两个链表的内容
while(phead)
{
if(phead->val != A->val)
{
return false;;
}
else {
phead = phead->next;
A= A->next;
}
}
return true;
}
};
7. 输入两个链表,找出它们的第一个公共结点。OJ链接
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
int lenA = 0, lenB = 0;
struct ListNode* curA = headA;
struct ListNode* curB = headB;
int range = 0;
//计算AB链表节点数的差值range
while(curA->next)
{
lenA++;
curA = curA->next;
}
while(curB->next)
{
lenB++;
curB = curB->next;
}
//相交链表最后一个节点一定相同
if(curA != curB)
{
return NULL;
}
range = abs(lenB - lenA);
//假设链表A的步长大的
struct ListNode* longerlist = headA,*shortlist = headB;
printf("%d %d",longerlist->val,shortlist->val);
if(lenB - lenA > 0)
{
longerlist = headB;
shortlist = headA;
}
//那么步长大的走range步
while(range--)
{
longerlist = longerlist->next;
}
while(longerlist != shortlist)
{
longerlist = longerlist->next;
shortlist = shortlist->next;
}
return longerlist;
}
8. 给定一个链表,判断链表中是否有环。OJ链接
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
struct ListNode* fast = head;
struct ListNode* slow = head;
while(fast && fast->next)//没有环
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
return true;
}
}
return false;
}
9. 给定一个链表,返回链表开始入环的第一个结点。 如果链表无环,则返回 NULL OJ链接
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* fast = head;
struct ListNode* slow = head;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
while(head != slow)//从头节点和相遇点分别开始走,相等时退出循环
{
head = head->next;
slow = slow->next;
}
return head;
}
}
return NULL;
}
10. 给定一个链表,每个结点包含一个额外增加的随机指针,该指针可以指向链表中的任何结点或空结点。要求返回这个链表的深度拷贝。OJ链接
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
struct Node* copyRandomList(struct Node* head) {
struct Node* cur = head;
struct Node* next = head;
struct Node* copyhead = NULL;
struct Node* copytail = NULL;
//将复制节点链接在原节点之后
while(cur)
{
struct Node* next = cur->next;
//新建复制节点
struct Node* copynode = (struct Node*)malloc(sizeof(struct Node));
copynode->val = cur->val;
//链接
cur->next = copynode;
copynode->next = next;
cur = next;
}
//printf("%d",head->next->next->next->val);
//根据原链表的random链接关系 链接 复制链表的random关系
cur = head;
while(cur)
{
next = cur->next;
if(cur->random == NULL)
{
next->random = NULL;
}
else
{
next->random = cur->random->next;
}
cur = next->next;
}
//剪下来
cur = next = head;
while(cur)
{
next = cur->next;
if(copyhead == NULL)
{
copyhead = copytail = next;
cur = next->next;
}
else
{
copytail->next = next;
copytail = next;
cur->next = next->next;
cur = next->next;
}
}
return copyhead;
}