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

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

第二章 链表问题

第一题:翻转部分单向链表
本题有可能存在换头问题
1.先判断是否满足条件
2.找到第from-1和to+1个节点,把翻转部分先翻转,然后正确连接
3.如果fpr!=NULL直接返回新的头节点;如果为NULL,说明翻转部分是包含头节点的,则连接后返回head;

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
ListNode* reversePartOfList(ListNode* head,int from,int to){
	if (head==NULL||head->next==NULL)
	{
		return head;
	}
	int len=0;
	ListNode* cur=head;
	ListNode* fpr=NULL;
	ListNode* tpo=NULL;
	while (cur!=NULL)
	{
		++len;
		fpr=len==from-1?cur:fpr;
		tpo=len==to+1?cur:tpo;
		cur=cur->next;
	}
	if(from>to||from<1||to>len){
		return head; 
	}
	//不知道怎么分配翻转用的pre、cur、next;
	ListNode* pre=NULL;
	pre=fpr==NULL?head:fpr->next;
	pre->next=tpo;
	cur=pre->next;
	ListNode* next=NULL;
	while (cur!=tpo)
	{
		next=cur->next;
		cur->next=pre;
		pre=cur;
		cur=next;
	}
	if (fpr!=NULL)
	{
		fpr->next=cur;
		return head;
	}
	return pre;//之前return了cur,而cur是null的
}

第二题:判断一个链表是否为回文结构
方法三:不需要栈和其他数据结构,只用三个变量,额外空间复杂度为O(1),就可以在时间复杂度为O(N)内完成所有过程
1.改变链表右半区的结构,使其翻转,指向中间节点
2.两端节点头同时向中间点移动并比较是否相等,即判断是否回文,当出现否的情况是直接break循环
3.恢复链表原先结构,返回检查结果

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
bool isPalindrome(ListNode* head){
	if(head==NULL||head->next==NULL){
		return true;
	}
	ListNode* n1=head,*n2=head;
	//找到中间点n1
	while (n2->next!=NULL&&n2->next->next!=NULL)
	{
		n1=n1->next;
		n2=n2->next->next;
	}
	bool res=true;
	//开始翻转
	ListNode* n3=NULL;
	n2=n1->next;
	n1->next=NULL;
	while (n2!=NULL)
	{
		n3=n2->next;
		n2->next=n1;
		n1=n2;
		n2=n3;
	}
	//之前没有保存最后一个节点导致检查完后无法复原,同时也没有用n2代替head进行接下来的检查
	n3=n1;
	n2=head;
	//检查回文
	while(head!=NULL&&n1!=NULL){//之前用的head去比较,那样会改变原head,与本愿相违
		if (head->val!=n1->val)
		{
			res=false;
			break;//少加了个break
		}
		head=head->next;
		n2=n2->next;
	}
	n1=n3->next;
	n3->next=NULL;
	while(n1!=NULL){
		n2=n1->next;
		n1->next=n3;
		n3=n1;
		n1=n2;
	}
	return res;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值