2.c++_leetcode206,92题单链表逆序问题

一、Leetcode206题

1.题目

  已知链表头结点指针head,将链表逆序。(不可申请额外空间)

2.分析

  首先看题,不可申请额外空间,但是能创建指针,这很关键

  一般链表逆序的思路都是新建一个新指针指向null,这个指针可以从新串的末尾开始逐步扫描到前面

3.代码

#include <stdio.h>

struct ListNode{
  int val;
  ListNode *next;
  ListNode(int x):val(x),next(NULL){}  //构造函数写法,中间用逗号连接
};

class Solution{
  public:
    ListNode* reverseList(ListNode *head){
	  //创建新的头结点,新串每次从尾部添加head指向的节点
	  ListNode *new_head = NULL;
	  while(head){
	    ListNode *next = head->next;
		head->next = new_head;
		new_head = head;
		head = next;
	  }
	  return new_head;
	}
};

int main(){
  ListNode a(1);
  ListNode b(2);
  ListNode c(3);
  ListNode d(4);
  ListNode e(5);
  a.next = &b;
  b.next = &c;
  c.next = &d;
  d.next = &e;
  e.next = NULL;
  ListNode *head = &a;
  printf("Before Reversed:\n");
  while(head){
    printf("%d\n",head->val);
	head = head->next;
  }
  Solution solve;
  head = solve.reverseList(&a);
  printf("After reversed:\n");
  while(head){
    printf("%d\n",head->val);
	head = head->next;
  }
  return 0;
}

二、Leetcode92题

1.题目

  已知链表头结点指针head,将链表从位置m到n逆序。不可申请额外空间。

2.分析

  本题相比上面需要考虑的东西会更多一些

  1.默认1<=m<n

  2.m=1时,需要考虑特殊情况

    如果m=1,返回结果的头结点是原来待逆序子串的头

    不然,返回结果的头结点就是原来的头结点

  3.此外还要考虑子串逆序后的重连操作

3.代码

#include <stdio.h>
struct ListNode{
  int val;
  ListNode *next;
  ListNode(x):val(x),next(NULL){}  //构造函数
};

class Solution{
  public:
  ListNode* reverseBetween(ListNode *head,int m,int n){
    ListNode *result = head;
    ListNode *pre_head = NULL;
	//1.pre_head与head一起往前,找到待逆转子串的头
	while(head&&--m){
	  pre_head = head;
	  head = head->next;
	} //假设m是1,直接退出,假设m为2,执行一轮,head是2,prehead是1,满足
	//2.尾部记录
	ListNode *modify_list_tail = head;
	//3.子串逆序
	ListNode *new_head = NULL;   //新头从尾部开始等着head补进来
	ListNode *next = head;       //防止短链的next指针
	int change_len = m-n+1;
	while(head&&change_len){ //基本是运行子串长度的个数
	  next = head->next;
	  head->next = new_head;
	  new_head = head;
	  head = next;
	  change_len--;
	}//可以看到head最后是待逆序子串的后继
	//4.尾部相连
	modify_list_tail->next = head;
	//5.头部相连
	if(pre_head){ //pre_head存在,正常情况,直接连接
	  pre_head->next = new_head;
	}
	else
	  result = new_head;
	return result;
  }
};

int main(){
  ListNode a(10);
  ListNode b(20);
  ListNode c(30);
  ListNode d(40);
  ListNode e(50);
  a.next = &b;
  b.next = &c;
  c.next = &d;
  d.next = &e;
  e.next = NULL;
  ListNode *head = reverseBetween(&a,2,4);
  while(head){
    printf("%d\n",head->val);
	head = head->next;
  }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值