链表面试题

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值