2.链表相关面试题

对于左神课上讲到的算法题,自己从头到尾基本敲了一遍,因为是先回忆了几道题后,有重新打开网课看了一下题目,因此顺序可能和讲课顺序不太一样,不过应该基本都实现了。

这里先给两个链表结点数据结构,一个带有随机指针,一个不带。

class ListNode {
public:
	ListNode();
	ListNode(int val);


	int val;
	ListNode* next;
};


//带随机指针的链表
class ListNode1 {
public:
	ListNode1();
	ListNode1(int val);


	int val;
	ListNode1* next;
	ListNode1* random;
};

1.判断是否有环

bool test01(ListNode* node) {
	ListNode* slow = node;
	ListNode* fast = node;

	while (fast->next != nullptr && fast->next->next != nullptr) {
		slow = slow->next;
		fast = fast->next->next;
		
		if (fast == slow) {
			return true;
		}
	}
	return false;

}

2.判断两个无环链表的第一个相交结点

ListNode* test02(ListNode* node1, ListNode* node2) {
	if (node1 == nullptr || node2 == nullptr) {
		return nullptr;
	}

	ListNode* head1 = node1;
	ListNode* head2 = node2;

	while (head1 != nullptr && head2 != nullptr) {
		if (head1 == head2) return head1;
		head1 = head1->next == nullptr ? node2 : head1->next;
		head2 = head2->next == nullptr ? node1 : head2->next;
	}

	return nullptr;

}

3.深拷贝带随机指针的链表

ListNode1* test03(ListNode1* head) {
	/*
	* //哈希表
	if (node == nullptr) {
		return nullptr;
	}
	ListNode1* head = node;
	ListNode1* newHead = new ListNode1();
	ListNode1* tmp = newHead;

	std::unordered_map<ListNode1*, ListNode1*> map;
	while (head != nullptr) {
		ListNode1* newNode = new ListNode1(head->val);
		map[head] = newNode;
		tmp->next = newNode;
		tmp = tmp->next;
		head = head->next;
	}

	head = node;
	tmp = newHead->next;

	while (head != nullptr) {
		tmp->random = map[head->random];
		tmp = tmp->next;
		head = head->next;
	}
	
	return newHead->next;
	*/

	//指针
	if (head == nullptr) return nullptr;
	ListNode1* node1 = head;
	ListNode1* newHead = new ListNode1(0);

	while (node1 != nullptr) {
		ListNode1* newNode = new ListNode1(node1->val);
		ListNode1* next = node1->next;
		node1->next = newNode;
		newNode->next = next;
		node1 = next;
	}
	node1 = head;
	while (node1 != nullptr) {
		if (node1->random != nullptr)
			node1->next->random = node1->random->next;
		node1 = node1->next->next;
	}
	node1 = head;
	newHead->next = head->next;
	ListNode1* node2 = newHead->next;
	while (node1 != nullptr) {
		node1->next = node2->next;
		node1 = node1->next;
		if (node2->next != nullptr) {
			node2->next = node2->next->next;
			node2 = node2->next;
		}
	}

	return newHead->next;
}

4.翻转链表

ListNode* test04(ListNode* node) {
	ListNode* cur = node;
	ListNode* pre = nullptr;

	while (cur != nullptr) {
		ListNode* next = cur->next;
		cur->next = pre;
		pre = cur;
		cur = next;
	}
	return pre;
}

5.输入链表头结点,奇数长度返回中点,偶数长度返回上中点

ListNode* test05(ListNode* head) {
	if (head == nullptr || head->next == nullptr || head->next->next == nullptr) {
		return head;
	}

	ListNode* fast = head;
	ListNode* slow = head;
	while (fast->next != nullptr && fast->next->next != nullptr) {
		slow = slow->next;
		fast = fast->next->next;
	}

	return slow;
}

6.输入链表头节点 奇数长度返回中点 偶数长度返回下中点

ListNode* test06(ListNode* head) {
	if (head == nullptr || head->next == nullptr) return head;
	if (head->next->next == nullptr) return head->next;
	
	ListNode* slow = head->next;
	ListNode* fast = head->next;
	while (fast->next != nullptr && fast->next->next != nullptr) {
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow;
}

7.输入链表头节点 奇数长度返回中点前一个 偶数长度返回上中点前一个

ListNode* test07(ListNode* head) {
	if (head == nullptr || head->next == nullptr) return nullptr;
	if (head->next->next == nullptr) return head;

	ListNode* slow = head;
	ListNode* fast = head->next->next;

	while (fast->next != nullptr && fast->next->next != nullptr) {
		slow = slow->next;
		fast = fast->next->next;
	}

	return slow;
}

8.输入链表头节点 奇数长度返回中点前一个 偶数长度返回上中点前一个

ListNode* test08(ListNode* head) {
	if (head == nullptr || head->next == nullptr) return nullptr;
	if (head->next->next == nullptr) return head;

	ListNode* slow = head;
	ListNode* fast = head->next;

	while (fast->next != nullptr && fast->next->next != nullptr) {
		slow = slow->next;
		fast = fast->next->next;
	}

	return slow;
}

9.回文链表

bool test09(ListNode* head) {
	if (head == nullptr) {
		return false;
	}
	if (head->next == nullptr) {
		return true;
	}

	ListNode* slow = head;
	ListNode* fast = head;
	while (fast->next != nullptr && fast->next->next != nullptr) {
		slow = slow->next;
		fast = fast->next->next;
	}

	ListNode* head2 = slow->next;
	slow->next = nullptr;
	//使用之前写好的翻转链表
	ListNode* head2 = test04(head2);
	fast = head2;
	slow = head;
	while (head2->next != nullptr) {
		if (slow->val != head2->val) return false;
		slow = slow->next;
		fast = fast->next;
	}
	return true;
}

10.把单向链表按某值划分为左边小,中间相等,右边大的形式

ListNode* test10(ListNode* head, int val) {
	if (head == nullptr || head->next == nullptr) {
		return head;
	}

	ListNode* sh = nullptr;
	ListNode* se = nullptr;
	ListNode* eh = nullptr;
	ListNode* ee = nullptr;
	ListNode* bh = nullptr;
	ListNode* be = nullptr;

	ListNode* node = head;
	while (node != nullptr) {
		ListNode* next = node->next;
		if (node->val < val) {
			if (sh == nullptr) {
				sh = head;
				se = head;
			}
			else {
				se->next = head;
				se = head;
			}
		}
		else if (node->val == val) {
			if (eh == nullptr) {
				eh = head;
				ee = head;
			}
			else {
				ee->next = head;
				ee = head;
			}
		}
		else {
			if (bh == nullptr) {
				bh = head;
				be = head;
			}
			else {
				be->next = head;
				be = head;
			}
		}
		node = next;
	}
	se->next = eh;
	ee->next = bh;
	be->next = nullptr;

	return sh;

}

网课地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值