oj
无头单链表删除指定位置的值
方法:将指定位置下一个的值给指定位置,删除指定位置节点。(替换法删除,但是无法删除尾节点)
移除链表元素
给一个链表的头结点head和一个整数val,删除链表中所有满足Node val==val的节点,并返回新的头节点。
方法一:在原链表上删除
方法二:新造newnode,遍历原链表将非val值的节点尾插到newnode
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val)
{
struct ListNode* cur=head;
struct ListNode* prev=NULL;
while(cur)
{
if(cur->val==val)
{
if(cur==head)
{
head=cur->next;
free(cur);
cur=head;
}
else
{
prev->next=cur->next;
free(cur);
cur=prev->next;
}
}
else
{
prev=cur;
cur=cur->next;
}
}
return head;
}
查找一个链表的中间节点
给一个单链表的头节点head,找出并返回中间节点,若果有两个中间节点,则返回第二个中间节点。
方法 一:先遍历一遍算长度,在遍历一遍到中间节点
方法二:快慢指针,慢指针一次走一个节点,快指针一次走两个节点,快指针到尾结点时,慢指针到中间节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* fastpoint,*slowpoint;
fastpoint=head;
slowpoint=head;
while(fastpoint&&fastpoint->next)
{
fastpoint=fastpoint->next->next;
slowpoint=slowpoint->next;
}
return slowpoint;
}
反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode*point1,*point2,*point3;
point1=NULL;
point2=head;
if(point2)
{
point3=point2->next;
}
while(point2)
{
point2->next=point1;
point1=point2;
point2=point3;
if(point3)
{
point3=point3->next;
}
}
return point1;
}
链表中倒数第k个节点
给一个带你链表的头节点,找出并返回倒数第k个节点
方法一:快慢指针,快指针先走k步,快慢指针在一起走知道快指针到NULL
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
*
* @param pListHead ListNode类
* @param k int整型
* @return ListNode类
*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
struct ListNode* fast=pListHead,*slow=pListHead;
while(k--)
{
if(fast==NULL)
return NULL;
fast=fast->next;
}
while(fast)
{
fast=fast->next;
slow=slow->next;
}
return slow;
}
合并两个有序链表
将两个升序链表合并为一个新 的升序链表订单回,新链表是通过拼接给定的两个链表的所有节点组成的
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
struct ListNode* newhead=NULL,*tail=NULL;
if(list1==NULL)
return list2;
if(list2==NULL)
return list1;
while(list1 && list2)
{
if(list1->val<list2->val)
{
if(tail==NULL)
{
newhead=list1;
tail=newhead;
}
else
{
tail->next=list1;
tail=tail->next;
}
list1=list1->next;
}
else
{
if(tail==NULL)
{
newhead=list2;
tail=newhead;
}
else
{
tail->next=list2;
tail=tail->next;
}
list2=list2->next;
}
}
if(list1)
tail->next=list1;
if(list2)
tail->next=list2;
return newhead;
}
相交链表
给出两个单链表的头节点
1:先遍历计算A与B的长度并判断是否相交
2:长的链表下走差距步
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *cura=headA,*curb=headB;
int lena=0,lenb=0;
while(cura->next)
{
lena++;
cura=cura->next;
}
while(curb->next)
{
lenb++;
curb=curb->next;
}
if(cura!=curb)
{
return NULL;
}
struct ListNode * longlist=headA;
struct ListNode * shortlist=headB;
if(lena<lenb)
{
longlist=headB;
shortlist=headA;
}
int gap=abs(lena-lenb);
while(gap--)
{
longlist=longlist->next;
}
while(longlist!=shortlist)
{
longlist=longlist->next;
shortlist=shortlist->next;
}
return longlist ;
}
复杂度O(N)
链表分割
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
#include <cstddef>
#include <cstdlib>
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
struct ListNode* biglist,*btail,*smalllist,*stail;
biglist=btail=( struct ListNode*)malloc(sizeof( struct ListNode*));
smalllist=stail=( struct ListNode*)malloc(sizeof( struct ListNode*));
ListNode* cur=pHead;
while(cur)
{
if(cur->val<x)
{
stail->next=cur;
stail=stail->next;
}
else
{
btail->next=cur;
btail=btail->next;
}
cur=cur->next;
}
stail->next=biglist->next;
btail->next=NULL;
struct ListNode *head =smalllist->next;
free(smalllist);
free(biglist);
return head;
}
};
判断回文链表
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode*point1,*point2,*point3;
point1=NULL;
point2=head;
if(point2)
{
point3=point2->next;
}
while(point2)
{
point2->next=point1;
point1=point2;
point2=point3;
if(point3)
{
point3=point3->next;
}
}
return point1;
}
struct ListNode* middleNode(struct ListNode* head)
{
struct ListNode* fastpoint,*slowpoint;
fastpoint=head;
slowpoint=head;
while(fastpoint&&fastpoint->next)
{
fastpoint=fastpoint->next->next;
slowpoint=slowpoint->next;
}
return slowpoint;
}
public:
bool chkPalindrome(ListNode* A) {
struct ListNode* cur=A;
struct ListNode* ret=reverseList(middleNode(A));
while(cur&&ret)
{
if(cur->val!=ret->val)
{
return false;
}
cur=cur->next;
ret=ret->next;
}
return true;
}
};
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *cura=headA,*curb=headB;
int lena=0,lenb=0;
while(cura->next)
{
lena++;
cura=cura->next;
}
while(curb->next)
{
lenb++;
curb=curb->next;
}
if(cura!=curb)
{
return NULL;
}
struct ListNode * longlist=headA;
struct ListNode * shortlist=headB;
if(lena<lenb)
{
longlist=headB;
shortlist=headA;
}
int gap=abs(lena-lenb);
while(gap--)
{
longlist=longlist->next;
}
while(longlist!=shortlist)
{
longlist=longlist->next;
shortlist=shortlist->next;
}
return longlist ;
}
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
struct ListNode * slowpoint=head,*fastpoint=head;
while(fastpoint&&fastpoint->next)
{
slowpoint=slowpoint->next;
fastpoint=fastpoint->next->next;
if(slowpoint==fastpoint)
return true;
}
return false;
}