经典十二道链表笔试题!

1. 删除链表中等于给定值val的所有节点

/**
 * 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 head;
	}
	Node* pPre = head;
	Node* pCur = head->next;
	while (pCur != NULL) {
		if (val == pCur->val) {
			pPre->next = pCur->next;
			pCur = pCur->next;
		}
		else {
			pPre = pCur;
			pCur = pCur->next;
		}
	}
	if (val == head->val) {
		head = head->next;
	}
	return head;
}

2.反转一个单链表。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

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

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

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

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

}

4.输入一个链表,输出该链表中倒数第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) {
		if (pListHead == NULL) {
			return NULL;
		}
		Node* pSlow = pListHead;
		Node* pFast = pListHead;
		while (k > 0 && pFast != NULL) {
			pFast = pFast->next;
			k--;
		}
		if (pFast == pListHead || (k > 0 && pFast == NULL)) {
			return NULL;
		}
		while (pFast != NULL) {
			pSlow = pSlow->next;
			pFast = pFast->next;
		}
		return pSlow;
	}
};

5.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

/**
 * 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 == NULL)
		return l2;
	if (l2 == NULL)
		return l1;
	if (l1->val < l2->val) {
		l1->next = mergeTwoLists(l1->next, l2);
		return l1;
	}
	else {
		l2->next = mergeTwoLists(l1, l2->next);
		return l2;
	}
}

6. 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 。

/*
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
		if (pHead == NULL) {
			return NULL;
		}
		ListNode* lessList = new ListNode(0);
		ListNode* greatList = new ListNode(0);
		ListNode* pTail1 = lessList;
		ListNode* pTail2 = greatList;
		ListNode* pCur = pHead;
		while (pCur) {
			if (pCur->val < x) {
				pTail1->next = pCur;
				pTail1 = pTail1->next;
			}
			else {
				pTail2->next = pCur;
				pTail2 = pTail2->next;
			}
			pCur = pCur->next;
		}
		pTail2->next = NULL;
		pTail1->next = greatList->next;
		return lessList->next;
	}
};

7.在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点, 重复的结点不保留,返回链表头指针

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
		val(x), next(NULL) {
	}
};
*/
class Solution {
public:
	ListNode* deleteDuplication(ListNode* pHead)
	{
		if (pHead == NULL)
			return pHead;

		ListNode *pPre = NULL; //指向前面最晚访问过的不重复结点
		ListNode *pCur = pHead; //指向当前处理的结点
		ListNode *pNext = NULL; //指向当前处理结点后面结点

		while (pCur != NULL)
		{
			//当前结点pCur,(其实是p指向当前结点),与它下一个结点pCur->next的val相同,说明要删掉有这个val的所有结点
			if (pCur->next != NULL && pCur->next->val == pCur->val)
			{
				pNext = pCur->next;

				//找到pNext,它指向最后一个与pCur val相同的结点,那pCur 到 pNext (包含) 都是要删除的
				while (pNext != NULL && pNext->next != NULL && pNext->next->val == pCur->val)
				{
					pNext = pNext->next;
				}

				//如果pCur指向链表中第一个元素,pCur -> ... -> pNext ->... , 要删除pCur到pNext, 将指向链表第一个元素的指针pHead指向pNext->next。
				if (pCur == pHead)
				{
					pHead = pNext->next;
				}
				else//如果pCur不指向链表中第一个元素,pPre -> pCur ->...->pNext ->... ,要删除pCur到pNext,即pPre->next = pNext->next
				{
					pPre->next = pNext->next;
				}
				//当前处理的pCur要向链表尾部移动
				pCur = pNext->next;
			}
			else
			{
				pPre = pCur;
				pCur = pCur->next;
			}
		}
		return pHead;
	}
};

8.链表的回文结构

/*
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 == NULL)
			return false;
		else if (A->next == NULL)
			return true;
		//快慢指针找出中间节点
		ListNode* qFast = A;
		ListNode* qSlow = A;
		while (qFast != NULL && qFast->next != NULL)
		{
			qFast = qFast->next->next;
			qSlow = qSlow->next;
		}
		//反转
		ListNode* p = qSlow->next;
		ListNode* p1 = p->next;
		while (p != NULL)
		{
			p->next = qSlow;
			qSlow = p;
			p = p1;
			p1 = p1->next;
		}

		while (A != qSlow)
		{
			if ((A->val) != (qSlow->val))
			{
				return false;
			}
			else {
				if (A->next == qSlow)
				{
					return true;
				}
				A = A->next;
				qSlow = qSlow->next;
			}
		}
		return true;

	}
};

9.求链表的相交节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
	typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
	if (NULL == headA || NULL == headB)
		return NULL;
	//确认两个链表是否相交
	ListNode* pTailA = headA;
	ListNode* pTailB = headB;
	int sizeA = 1;
	int sizeB = 1;
	//找headA链表中的最后一个节点
	while (pTailA->next) {
		sizeA++;
		pTailA = pTailA->next;
	}
	//找headB链表中的最后一个节点
	while (pTailB->next) {
		sizeB++;
		pTailB = pTailB->next;
	}
	if (pTailA != pTailB) {
		return NULL;
	}
	//两个链表已相交
	int gap = sizeA - sizeB;
	ListNode* pCurA = headA;
	ListNode* pCurB = headB;
	if (gap > 0) {
		while (gap--) {
			pCurA = pCurA->next;

		}
	}
	else {
		while (gap++) {
			pCurB = pCurB->next;
		}
	}
	while (pCurA != pCurB) {
		pCurA = pCurA->next;
		pCurB = pCurB->next;
	}
	return pCurA;
}

10.判断链表是否有环

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

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

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

12.给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的深度拷贝。

/*
// Definition for a Node.
class Node {
public:
	int val;
	Node* next;
	Node* random;

	Node() {}

	Node(int _val, Node* _next, Node* _random) {
		val = _val;
		next = _next;
		random = _random;
	}
};
*/
Node* BuyNode(int data) {
	Node* pNewNode = (Node*)malloc(sizeof(Node));
	if (NULL == pNewNode) {
		assert(0);
		return NULL;
	}
	pNewNode->val = data;
	pNewNode->next = NULL;
	pNewNode->random = NULL;
	return pNewNode;
}
class Solution {
public:
	Node* copyRandomList(Node* head) {
		if (NULL == head)
			return NULL;
		//在原链表中每个节点后插入值相同的新节点
		Node* pCur = head;
		while (pCur) {
			Node* pNewNode = BuyNode(pCur->val);
			pNewNode->next = pCur->next;
			pCur->next = pNewNode;
			pCur = pNewNode->next;
		}
		//给新节点的随机指针域赋值
		pCur = head;
		while (pCur) {
			Node* pNewNode = pCur->next;
			if (pCur->random)
				pNewNode->random = pCur->random->next;
			pCur = pNewNode->next;
		}
		//将新节点从原链表中拆下来
		pCur = head;
		Node* pNewHead = pCur->next;
		while (pCur->next) {
			Node* pNewNode = pCur->next;
			pCur->next = pNewNode->next;
			pCur = pNewNode;
		}
		return pNewHead;
	}
};
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值