难度中等393
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
基础知识:
反转指定下标(i 到 j)之间的元素,包括位置i和j对应的元素;
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int>vec = { 1,2,3,4,5,6,7,8 };
int i, j;
i = 2; j = 6;
reverse(vec.begin() + i, vec.begin() + j + 1);
for (int k = 0; k < vec.size(); k++) cout << vec[k];
}
输出结果:1 2 7 6 5 4 3 8
思路:
1、数组旋转起来比链表旋转起来简单多了吧!
2、所以把链表存储进数组,然后旋转数组,然后再根据数组的元素创建一个新的链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n)
{
vector<int> v1;
if(head == nullptr || head->next == NULL) return head;
ListNode* p1 = head;
while(p1)
{
v1.push_back(p1->val);
p1=p1->next;
}
m--;//由于数组是0开始的,但是链表的第几个元素,是从1开始数的,所以-1
n--;
reverse(v1.begin()+m,v1.begin()+n+1);
p1 = head;
for( auto num:v1)
{
p1->next = new ListNode(num);
p1=p1->next;
}
return head->next;
}
};
while(m<n)
{
int temp = v1[m];
v1[m] = v1[n];
v1[n] = temp;
m++;
n--;
}
等同于下面这一句,但是下面这一句是库函数效率更高
reverse(v1.begin()+m,v1.begin()+n+1);