面试算法 牛客题目 链表内指定区间反转

1.题目:链表内指定区间反转

题目解释:

 


2.算法:

链表反转


3.算法思想:(看代码!!!)

//算法的解释  链表 的 1 2 3 4 5 6 7   把 2  到  4    区间的链表反转  变成 1 4 3 2 5 6 7  
// 过程  开始
/*

//算法思想  : 
 
找到需要反转的开始节点  (第一个节点)n     和开始反转节点  n 之前的 节点 kk  
然后我们需要 开始 把这个节点 后面的节点反转  首先  把开始节点 n   连接   下一个节点 p1  的下一个节点  p2   ,
p1  连接  节点kk 的下一个节点      
节点kk  连接   节点 P1 
           
算法过程:演示
 
1.     1  3  2  4  5  6  7     怎么变过来的  首先  2节点 指向   4 节点     3节点 指向 2 节点    1 节点 指向   3节点       
2.     1  4  3  2  5  6  7     


4.代码:

/*************************************************
作者:She001
时间:2022/9/19
题目:链表内指定区间反转
将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。
例如:
给出的链表为 1\to 2 \to 3 \to 4 \to 5 \to NULL1→2→3→4→5→NULL, m=2,n=4m=2,n=4,
返回 1\to 4\to 3\to 2\to 5\to NULL1→4→3→2→5→NULL.

数据范围: 链表长度 0 < size \le 10000<size≤1000,0 < m \le n \le size0<m≤n≤size,链表中每个节点的值满足 |val| \le 1000∣val∣≤1000
要求:时间复杂度 O(n)O(n) ,空间复杂度 O(n)O(n)
进阶:时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)
示例1
输入:
{1,2,3,4,5},2,4

返回值:
{1,4,3,2,5}
复制
示例2
输入:
{5},1,1
复制
返回值:
{5}

***************************************************/

#include<bits/stdc++.h>
using namespace std;
typedef struct node
{
	int i;
	node *next;	
}; 

void print(node * head)
{
	node* pp= head;
	while(pp!=NULL)
	{
		cout<<pp->i<<"  ";
		pp=pp->next;
	}
	cout<<endl;
	
} 


//算法的解释  链表 的 1 2 3 4 5 6 7   把 2  到  4    区间的链表反转  变成 1 4 3 2 5 6 7  
// 过程  开始
/*

//算法思想  : 
 
找到需要反转的开始节点  (第一个节点)n     和开始反转节点  n 之前的 节点 kk  
然后我们需要 开始 把这个节点 后面的节点反转  首先  把开始节点 n   连接   下一个节点 p1  的下一个节点  p2   ,
p1  连接  节点kk 的下一个节点      
节点kk  连接   节点 P1 
		   

 
算法过程:演示
 
1.     1  3  2  4  5  6  7     怎么变过来的  首先  2节点 指向   4 节点     3节点 指向 2 节点    1 节点 指向   3节点       
2.     1  4  3  2  5  6  7     
 



*/ 

node * fangfa_1(node * head,int m,int n)
{
	
  //加个表头  这样好返回链表的头  有可能他是反转第一个节点 
    node* res = new node;
    res->i=-1;
    res->next=head;
    res->next = head;
    //前序节点
    node* pre = res;
    //当前节点
    node* cur = head;
    //找到 m  和他之前的节点 
    for(int i = 1; i < m; i++){
        pre = cur;   
        cur = cur->next;
    }
    //循环之后的节点的意义
	//节点  pre  是 节点 n  之前的节点
	// 节点  cur  就是   节点  n
	  
    
    //从m 反转到 n   
    for(int i = m; i < n; i++){
        node* temp = cur->next; //新建一个node  指针 指向 节点 n  的下一个节点  
        cur->next = temp->next; //节点n   指向的下一个的节点   等于    之前指向的下一个节点 的下一个节点 。 
        temp->next = pre->next; //节点 temp 指向的下一个节点   等于  节点 pre 指向下一个节点    意思就是 把节点temp  插入 到  节点 temp 的下一个 
        pre->next = temp;  // 意思就是 把节点temp  插入 到  节点 temp 的下一个 
    }
    //返回去掉表头
    return res->next;
	
		
} 

int main()
{
	
	//建立单链表 
	node *a1=new node;
	node *a2=new node;
	node *a3=new node;
	node *a4=new node;
	node *a5=new node;
	node *a6=new node;
	node *a7=new node;
	
	a1->i=1;//链表节点的复制 
	a2->i=2;
	a3->i=3;
	a4->i=4;
	a5->i=5;
	a6->i=6;
	a7->i=7;
	
	a1->next=a2;//链表的连接 
	a2->next=a3;
	a3->next=a4;
	a4->next=a5;
	a5->next=a6;
	a6->next=a7;
	a7->next=NULL;
	
	node * k=fangfa_1(a1,2,4);//反转链表的局部空间 
	print(k);//打印数据 
	
		
	
	

	return 	0;
} 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值