链表面试题

链表面试试题

1:编写一个程序,找到两个单链表相交的起始节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode Node;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if (headA == NULL || headB == NULL) {
return NULL;
}
 Node* lastA = headA;
 Node* lastB = headB;
int sizeA=1;
int sizeB=1;
while(lastA->next){
        sizeA++;
        lastA=lastA->next;
}
while(lastB->next){
        sizeB++;
        lastB=lastB->next;
}
if (lastA != lastB) {
return NULL;
}
 Node* curA = headA;
 Node* curB = headB;
int pos = sizeA - sizeB;
if (pos > 0) {
while (pos--) {
   curA = curA->next;
}
}
else {
while (pos++) {
   curB = curB->next;
}
}
while (curA != curB) {
  curA = curA->next;
  curB = curB->next;
}
return curA;
}

2:给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

typedef struct ListNode Node;
struct ListNode* partition(struct ListNode* head, int x) {
 Node* cur = head;
 Node* rhead = NULL, * rcur = NULL, * lhead = NULL, * lcur = NULL;
while (cur) {
if (cur->val < x) {
if (rhead == NULL) {
    Node* node = (Node*)malloc(sizeof(Node));
    node->val = cur->val;
    rhead=rcur = node;
}
else {
   Node* node = (Node*)malloc(sizeof(Node));
    node->val = cur->val;
    rcur->next = node;
    rcur = node;
}
}
else{
if (lhead == NULL) {
    Node* node = (Node*)malloc(sizeof(Node));
    node->val = cur->val;
    lhead=lcur = node;
}
else {
    Node* node = (Node*)malloc(sizeof(Node));
    node->val = cur->val;
    lcur->next = node;
    lcur = node;
}
}
  cur = cur->next;
}
if (rhead == NULL) {
return lhead;
}
if (lhead) {
  lhead->next = NULL;
}
 rcur->next = lhead;
return rhead;
}

3.给定一个链表,判断链表中是否有环。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode Node;
bool hasCycle(struct ListNode *head) {
    Node*pFast=head;
    Node*pSlow=head;
while(pFast&&pFast->next){
        pFast=pFast->next->next;
        pSlow=pSlow->next;
if(pFast==pSlow){
return true;
}
}
return false;
}

4:给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode Node;
struct ListNode *detectCycle(struct ListNode *head) {
if(head==NULL){
return NULL;
}
    Node*pFast=head;
    Node*pSlow=head;
    Node*pInput=head;
while(pFast&&pFast->next){
        pFast=pFast->next->next;
        pSlow=pSlow->next;
if(pFast==pSlow){
while(pInput!=pSlow){
            pInput=pInput->next;
            pSlow=pSlow->next;
}
return pInput;
}
}
return NULL;
}

5:翻转链表

typedef struct ListNode Node;
struct ListNode* reverseList(struct ListNode* head){
    Node*pre=NULL;
    Node*next=NULL;
while(head!=NULL){
        next=head->next;
        head->next=pre;
        pre=head;
        head=next;  
}
return pre;
}

6:删除链表中等于给定值 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;
 * };
 */
typedef struct ListNode Node;
struct ListNode* removeElements(struct ListNode* head, int val){
if (head == NULL) {
return NULL;
}
 Node* rhead = NULL;
 Node* cur = head;
while (cur) {
if (cur->val == val) {
if (rhead == NULL) {
    head = cur->next;
free(cur);
    cur = head;
}
else {
    rhead->next = cur->next;
free(cur);
    cur = rhead->next;
}
}
else{
  rhead = cur;
  cur = cur->next;
}
}
return head;
}

7:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
示例:输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL

struct ListNode* reverseBetween(struct ListNode* head, int m, int n){
    if(head==NULL||n<m){
        return head;
    }
    Node*cur=head;
    Node*start=cur;
    Node*end=cur;
    Node*next=NULL;
    Node*pre=NULL;
    for(int i=1;i<m;i++){
        start=cur;
        cur=cur->next;
        end=cur;
    }
    for(int i=0;i<=n-m;i++){
        next=cur->next;
        cur->next=pre;
        pre=cur;
        cur=next;
    }
    start->next=pre;
    end->next=cur;
    if(m==1){
        return pre;
    }
    return head;
}

8:请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。

示例:
输入: head = [4,5,1,9], node = 5
输出: [4,1,9]

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode Node;
void deleteNode(struct ListNode* node) {
  node->val=node->next->val;
    node->next=node->next->next;    
}

9:合并两个有序链表
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

typedef struct ListNode Node;
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    Node*head=(Node*)malloc(sizeof(Node));
    Node*p=head;
    while(l1!=NULL&&l2!=NULL){
        if(l1->val<=l2->val){
            p->next=l1;
            l1=l1->next;
        }
        else{
            p->next=l2;
            l2=l2->next;
        }
        p=p->next; 
    }
    if(l1!=NULL){
        p->next= l1;
    }
    else{
        p->next=l2;
    }
    return head->next;
}

10:返回中间结点

要求:给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

typedef struct ListNode Node;
struct ListNode* middleNode(struct ListNode* head){
    Node*pFast=head;
    Node*pSlow=head;
    while(pFast&&pFast->next){
        pFast=pFast->next->next;
        pSlow=pSlow->next;
    }
    return pSlow;
}

11:删除链表中的重复元素
要求:给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例:
输入:1->1->2
输出:1->2

typedef struct ListNode Node;
struct ListNode* deleteDuplicates(struct ListNode* head){
 if (head == NULL) {
  return NULL;
 }
 Node* cur = head;
 while (cur->next) {
  if (cur->val == cur->next->val) {
   cur->next = cur->next->next;
   continue;
  }
  else {
   cur = cur->next;
  }
 }
 return head;
}

12:删除链表中的重复元素II
要求:给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例:
输入: 1->2->3->3->4->4->5
输出: 1->2->5

typedef struct ListNode Node;
struct ListNode* deleteDuplicates(struct ListNode* head){
 if (head == NULL) {
  return NULL;
 }
 Node* pre = NULL;
 Node* cur = head;
 while (cur) {
  if (cur->next!=NULL&&cur->val == cur->next->val) {
   int value = cur->val;
   while (cur->next != NULL && cur->next->val == value) {
    cur = cur->next;
   }
   if (pre == NULL) {
    head = cur->next;
   }
   else {
    pre->next = cur->next;
   }
  }
  else {
   pre = cur;
  }
  cur = cur->next;
 }
 return head;
}

13:删除链表倒数第n个结点

要求:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.

typedef struct ListNode Node;
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
 if (head == NULL) {
  return NULL;
 }
 Node* pFast = head;
 Node* pSlow = head;
 int i = 0;
 while (pFast) {
  pFast = pFast->next;
  i++;
 }
 int j = i - n - 1;
 if (j < 0) {
  return head->next;
 }
 while (j--) {
  pSlow = pSlow->next;
 }
 pSlow->next = pSlow->next->next;
 return head;
}

14:两两交换链表中的结点

示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.

typedef struct ListNode Node;
struct ListNode* swapPairs(struct ListNode* head){
 if (head == NULL || head->next == NULL) {
  return head;
 }
 Node* p1 = head;
 Node* p2 = head->next;
 Node* p3 = NULL;
    Node*pre=(Node*)malloc(sizeof(Node));
 Node* temp = head->next;
 pre->next = head;
 while (1) {
  p3 = p2->next;
  p2->next = p1;
  pre->next = p2;
  pre = p1;
  pre->next = p3;
  if (p3 && p3->next) {
   p1 = p3;
   p2 = p1->next;
  }
  else {
   break;
  }
 }
 return temp;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值