《程序员代码面试指南》it名企算法与数据结构题目最优解(第二版)刷题笔记8

由于之前看了牛客网的数据结构和算法的课程知道了左神,现在找到了这本书当作入门书做做吧,虽然书的题解都是java实现的,但好在用c++实现难度不大。

第二章 链表问题

第一题:环形单链表的约瑟夫问题
据说著名的犹太历史学家Josephus有过以下故事:在罗马人占领桥塔帕特后,39个犹太人与Josephus 及他的朋友躲到一个洞中,39个犹太人宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第一个人开始报数,报数到3的人就自杀,然后再有下一个人重新报1,报数到3的人再自杀。这样依次下去,直到剩下最后一个人时,那个人可以自由选择自己的命运。这就是著名的约瑟夫问题。现在请用单向环形链表描述该结构并呈现整个自杀过程。

输入:一个环形单向链表的头节点head 和报数的值m。

返回:最后生存下来的节点,且这个节点自己组成环形单向链表,其他节点都删掉。

之前已经反复说过,如果要删除一个节点,则要找到他之前的节点。首先遍历找到head之前的节点pre,然后按题意做下去即可,时间复杂度为O(n*m)。

 struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
	
 };
 ListNode* josephusKill(ListNode *head, int m) {
	 if (head == NULL || head->next == head || m < 1) {
		 return head;
	 }
	 ListNode* pre = head;
	 while (pre->next != head) {
		 pre = pre->next;
	 }
	 int count = 0;
	 while (head->next!=head) {
		 if (count != m-1) {
			 pre = head;
			 head = head->next;
			 ++count;
		 }
		 else {
			 pre->next = head->next;
			 head = head->next;
			 count = 0;
		 }
	 }
	 return head;
 }

题目二:判断一个链表是否为回文结构
回文用栈结构。
方法一:直接全放进栈中再进行出栈比对,额外空间复杂度为O(n);
方法二:对方法一进行了优化,虽然也是利用栈结构,但只压入一半的节点。

#include
using namespace std;
 struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
	
 };
 bool isPalindrome2(ListNode *head) {
     //关键在如下两步找到右区间的头结点
	 ListNode* right = head->next, *cur = head;
	 while (cur->next != NULL || cur->next->next != NULL) {
		 right = right->next;
		 cur = cur->next->next;
	 }
	 stack stack;
	 while (cur->next != NULL) {
		 stack.push(cur->val);
		 cur = cur->next;
	 }
	 while (!stack.empty()) {
		 if (head->val != stack.top()) {
			 return false;
		 }
		 head = head->next;
		 stack.pop();
	 }
	 return true;
 }

你可能感兴趣的:(《程序员代码面试指南》it名企算法与数据结构题目最优解(第二版)刷题笔记8)