1.剑指offer 24.反转链表
(1)双指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* temp=NULL,*cur=NULL;
while(head){
temp=head->next;
head->next=cur;
cur=head;
head=temp;
}
return cur;
}
(2)递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
// 递归,递归函数返回已反转链表的头结点
if(head->next==NULL){
return head;
}
struct ListNode* temp=reverseList(head->next);//反转链表的头结点
//head一直在移动,而temp的位置不变
head->next->next=head;
head->next=NULL;
return temp;
}
(3)另一种双指针法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
// 另一种双指针法
if(head==NULL) return head;
struct ListNode* cur=head,*temp=NULL;
while(head->next){
temp=head->next->next;
head->next->next=cur;
cur=head->next;
head->next=temp;
}
head->next=NULL;
return cur;
}
最后一种解法参考
https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/solution/fan-zhuan-lian-biao-yi-dong-de-shuang-zhi-zhen-jia/
2.面试题02.01. 移除重复节点
(1)用数组记录每个值出现的次数
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeDuplicateNodes(struct ListNode* head){
int numcount[20000];
memset(numcount,0,sizeof(numcount));
// struct ListNode* p=head;
struct ListNode* dummy=(struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next=head;
struct ListNode* dummyhead=dummy;
while(head){
int index=head->val;
numcount[index]=numcount[index]+1;
if(numcount[index]==1){
dummy->next=head;
dummy=dummy->next;
}
head=head->next;
}
dummy->next=NULL;//没有这句就会返回全部。。。
return dummyhead->next;
}
(2)如果不使用临时缓冲区,那么就进行两次循环
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeDuplicateNodes(struct ListNode* head){
// 两次循环
struct ListNode *p=head,*q=head;
while(p){
q=p;
while(q && q->next){
if((q->next->val)==(p->val)){
//删除和p相同值的节点
q->next=q->next->next;
}
else{
q=q->next;
}
}
p=p->next;
}
return head;
}
3.剑指offer 52. 两个链表的第一个公共节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
// 双指针
if(headA==NULL || headB==NULL)
{
return NULL;
}
struct ListNode* p=headA,*q=headB;
while(p||q){
if(p==q){
return p;
}
p=p->next;
q=q->next;
if(p==NULL && q==NULL){
return NULL;
}
if(p==NULL){
p=headB;
}
if(q==NULL){
q=headA;
}
}
return NULL;
}
或者
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
// 双指针
if(headA==NULL || headB==NULL)
{
return NULL;
}
struct ListNode* p=headA,*q=headB;
while(p!=q){
if(p){
p=p->next;
}
else{
p=headB;
}
if(q){
q=q->next;
}
else{
q=headA;
}
}
return p;
}
4.876.链表的中间结点
(1)快慢指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* fast=head,*slow=head;
while(fast && fast->next){
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
5. 206.反转链表
和之前的一样
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
if(head==NULL) return NULL;
// // 递归
// if(head->next==NULL){
// return head;
// }
// struct ListNode *newhead=reverseList(head->next);
// head->next->next=head;
// head->next=NULL;
// return newhead;
// 迭代
struct ListNode *tmp=NULL,*cur=NULL;
while(head){
tmp=head->next;
head->next=cur;
cur=head;
head=tmp;
}
return cur;
}
6. 203.移除链表元素
(1)检查当前结点的下一个结点的val是否等于目标val,如果等于,则更改当前结点的下一个结点为下下个结点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
if(head==NULL) return NULL;
while(head && head->val==val){
head=head->next;
}
struct ListNode* prev=head;
while(prev && prev->next){
if(prev->next->val==val){
prev->next=prev->next->next;
}
else{
prev=prev->next;
}
}
return head;
}
(2)递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
if(head==NULL) return head;
// 递归
if(head->val==val)
{
head=removeElements(head->next,val);
}
else{
head->next=removeElements(head->next,val);
}
return head;
}
7.剑指offer 18.删除链表的节点
和前面的题都差不多
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteNode(struct ListNode* head, int val){
if(head==NULL) return NULL;
while(head->val==val){
head=head->next;
return head;
}
struct ListNode *p=head;
while(p){
if(p->next->val==val){
p->next=p->next->next;
break;
}
else{
p=p->next;
}
}
return head;
}
8. 面试题02.05 链表求和
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int listlength(struct ListNode *head){
int len=0;
struct ListNode *p=head;
while(p){
p=p->next;
len++;
}
return len;
}
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
int len1=listlength(l1);
int len2=listlength(l2);
if(len1<len2){
//用l1存和,把l1统一成较长的链表
struct ListNode* temp=l1;
l1=l2;
l2=temp;
int templen=len2;
len1=len2;
len2=templen;
}
int carry=0;//进位标志
struct ListNode* res=l1;
while(l1){
l1->val=(l1?l1->val:0)+(l2?l2->val:0)+carry;
carry=(l1->val)/10;
l1->val=l1->val%10;
if(l1->next==NULL) break;
l1=l1?l1->next:0;
l2=l2?l2->next:0;
}
if(carry==1){
l1->next=(struct ListNode*)malloc(sizeof(struct ListNode));
l1->next->val=1;
l1->next->next=NULL;
//为什么下面的代码不能连上,去掉第36行
// l1=(struct ListNode*)malloc(sizeof(struct ListNode));
// l1->val=1;
// l1->next=NULL;
}
return res;
}
在额外添加一个结点进位那里卡了好久,现在也还是不太懂为什么注释的地方的疑问,为什么这样不能把新结点和旧的链表连上。
9. 430.扁平化多级双向链表
(1)使用栈
参考https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list/solution/bian-ping-hua-duo-ji-shuang-xiang-lian-biao-by-lee/
"""
# Definition for a Node.
class Node(object):
def __init__(self, val, prev, next, child):
self.val = val
self.prev = prev
self.next = next
self.child = child
"""
class Solution(object):
def flatten(self, head):
"""
:type head: Node
:rtype: Node
"""
# 使用栈
if(head==None):
return head
dummy=Node(0,None,head,None)
stack=[]
pre=dummy
cur=head
stack.append(cur)
while(stack):
cur=stack.pop()
pre.next=cur
cur.prev=pre
if(cur.next):
stack.append(cur.next)
if(cur.child):
stack.append(cur.child)
cur.child=None
pre=cur
dummy.next.prev=None
return dummy.next
# # 递归
# p=head
# while(p->)
# return head
# def dfs(self,head,nexthead):
# # 递归
# p=head
# while(p.child==NULL):
# p=p->next
# if(p.next==NULL and p.child==NULL):
# tail=p;
# while(p.child):
# nexthead=p.next
# q=dfs(p.child,nexthead)
# p.next=q
# q.prev=p
# # p.child=NULL
# tail.next=nexthead
# nexthead.prev=tail
# return head
(2)dfs