1.反转单链表
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* n1=head;
if(!head)
{
return NULL;
}
struct ListNode* n2=head->next;
if(!n2)
{
return head;
}
struct ListNode* n3=n2->next;
n1->next=NULL;
n2->next=n1;
while(n2)
{
n1=n2;
n2=n3;
if(n3)
{
n3=n3->next;
n2->next=n1;
}
}
return n1;
}
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode node;
struct ListNode* reverseList(struct ListNode* head){
node* cur=head;
node* newnode=NULL;
if(!head)
{
return NULL;
}
node* nextnode=head->next;
while(cur)
{
cur->next=newnode;
newnode=cur;
cur=nextnode;
if(nextnode)
{
nextnode=nextnode->next;
}
}
return newnode;
}
2.删除链表中等于给定值 val 的所有节点。
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* newnode=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* node=newnode;
struct ListNode* cur=head;
newnode->next=NULL;
while(cur)
{
struct ListNode* r=cur->next;
if(cur->val==val)
{
free(cur);
cur=r;
}
else
{
node->next=cur;
node=cur;
node->next=NULL;
cur=r;
}
}
return newnode->next;
}
3.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。(快慢指针的问题)
输入:[1,2,3,4,5]
输出:此列表中的结点 3
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode node;
struct ListNode* middleNode(struct ListNode* head){
node* slow=head;
node* fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
4.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(!l1)
{
return l2;
}
else if(!l2)
{
return l1;
}
Node* head=NULL;
Node* tail=NULL;
while(l1 && l2)
{
if(l1->val<l2->val)
{
if(!tail)
{
head=tail=l1;
}
else
{
tail->next=l1;
tail=tail->next;
}
l1=l1->next;
}
else
{
if(!tail)
{
head=tail=l2;
}
else
{
tail->next=l2;
tail=tail->next;
}
l2=l2->next;
}
}
if(!l1)
{
tail->next=l2;
}
else
{
tail->next=l1;
}
return head;
}
5.输入一个链表,输出该链表中倒数第k个结点。(快慢指针的问题)
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
typedef struct ListNode Node;
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
Node* slow=pListHead;
Node* fast=pListHead;
while(k--)
{
if(!fast)
{
return NULL;
}
fast=fast->next;
}
while(fast)
{
slow=slow->next;
fast=fast->next;
}
return slow;
}
};
6.编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前
给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
// write code here
struct ListNode* LessHead = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* LessNode = LessHead;
struct ListNode* GreatHead = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* GreatNode = GreatHead;
while (pHead)
{
int num = pHead->val;
if (num < x)
{
LessNode->next = pHead;
LessNode = LessNode->next;
}
else
{
GreatNode->next = pHead;
GreatNode = GreatNode->next;
}
pHead = pHead->next;
}
LessNode->next = GreatHead->next;
GreatNode->next = NULL;
struct ListNode* list = LessHead->next;
free(LessHead);
free(GreatHead);
return list;
}
};
7.在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
if (!pHead)
{
return pHead;
}
struct ListNode* before = pHead;
struct ListNode* curhead = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* cur = curhead;
struct ListNode* src = pHead->next;
while (before)
{
if (!src)
{
cur->next = before;
before = before->next;
}
else if (src->val != before->val)
{
cur->next = before;
cur = cur->next;
before = before->next;
src = src->next;
}
else
{
int num = before->val;
while (src&&src->val == num)
{
src = src->next;
}
if (!src)
{
cur->next = NULL;
return curhead->next;
}
before = src;
src = src->next;
}
}
return curhead->next;
}
};
8.对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:1->2->2->1 返回:true
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code here
if (!A)
{
return false;
}
struct ListNode* slow = A;
struct ListNode* fast = A;
struct ListNode* node;
struct ListNode* n1=NULL;
struct ListNode* n2 = NULL;
struct ListNode* n3 = NULL;
if (!A->next)
{
return false;
}
while (fast&&fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
node = slow;
n1 = slow;
if (n1)
{
n2 = n1->next;
if (n2)
{
n3 = n2->next;
}
}
while (n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if (n3)
{
n3 = n3->next;
}
}
while (A != slow)
{
if (A->val != n1->val)
{
return false;
}
A = A->next;
n1 = n1->next;
}
return true;
}
};
9.编写一个程序,找到两个单链表相交的起始节点。
/**
* 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;
int i=0;
struct ListNode* NodeA=headA;
struct ListNode* NodeB=headB;
if(!headA||!headB)
{
return NULL;
}
while(NodeA)
{
lenA++;
NodeA=NodeA->next;
}
while(NodeB)
{
lenB++;
NodeB=NodeB->next;
}
if(lenA<lenB)
{
for(i=0;i<lenB-lenA;i++)
{
headB=headB->next;
}
}
else
{
for(i=0;i<lenA-lenB;i++)
{
headA=headA->next;
}
}
while(headA!=headB)
{
headA=headA->next;
headB=headB->next;
}
if(headA==headB)
{
return headA;
}
else
{
return NULL;
}
}
10.给定一个链表,判断链表中是否有环。(同向而行,不同速度,是否相遇)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
struct ListNode* slow=head;
struct ListNode* fast=head;
if(!head||!head->next)
{
return false;
}
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(fast==slow)
{
return true;
}
}
return false;
}
11.给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* slow=head;
struct ListNode* fast=head;
if(!head||!head->next)
{
return NULL;
}
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(fast==slow)
{
break;
}
}
if(fast==slow)
{
while(head!=slow)
{
head=head->next;
slow=slow->next;
}
return head;
}
return NULL;
}