idea:参考上一道全部反转,所以反转链表部分代码实现,我觉得重点在于集中不同情况的分类讨论。一共四类情况需要考虑,有前有后,有前无后,有后无前,无前无后。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        ListNode* p=head, *q=nullptr, *m=nullptr;    //三个指针实现反转任务
        ListNode* top=head;      //top在有前的情况下记录“前指针”
        int i=1;
        while(p!=nullptr){      //传入有效链表
            if(i==left-1){
                top=head;
            }
            if(i==left)
                q=head;
            if(i>left && i<right+1){    //注意反转是从left+1项开始
                m=head;
                head=head->next;
                m->next=q;
                q=m;
                i++;
                continue;
            }
            if(i==right && head->next==nullptr){    //无后情况,分有前和无前
                if(left==1){
                    return q;
                }
                else{
                    top->next->next=nullptr;
                    top->next=q;
                    return p;
                }
            }
            if(i==right+1){      //有后情况,分有前和无前
                if(left>1){
                    top->next->next=head;
                    top->next=q;
                    return p;
                }
                else{
                    top->next=head;
                    return q;
                }
            }
            head=head->next;
            i++;
        }
        return nullptr;
    }
};
 
复杂度:
时间复杂度应该为O(n)
空间复杂度:应该为O(1)
 
进阶: ①递归反转   idea:上面使用的迭代法,还可以使用递归来实现反转的部分,代码略
 
②穿针引线   idea: 题解提供了一种新思路,遍历到反转部分是,将每个遍历的结点插入到反转部分的起点
 

class Solution {
public:
ListNode *reverseBetween(ListNode *head, int left, int right) {
// 设置 dummyNode 是这一类问题的一般做法
ListNode *dummyNode = new ListNode(-1);
dummyNode->next = head;
ListNode *pre = dummyNode;
for (int i = 0; i < left - 1; i++) {
pre = pre->next;
}
ListNode *cur = pre->next;
ListNode *next;
for (int i = 0; i < right - left; i++) {
next = cur->next;
cur->next = next->next;
next->next = pre->next;
pre->next = next;
}
return dummyNode->next;
}
};

  • 时间复杂度:O(N)O(N),其中 NN 是链表总节点数。最多只遍历了链表一次,就完成了反转。

  • 空间复杂度:O(1)O(1)。只使用到常数个变量。

最新文章

  1. .net开发笔记(十六) 对前部分文章的一些补充和总结
  2. ADO.Net 增、删、改、查(基本项)
  3. 复习sqldataread
  4. NPOI操作excel之写入数据到excel表
  5. 使用WCF 测试客户端测试你的WCF服务
  6. Java技术路线图
  7. iOS 图片实现马赛克效果
  8. 对 COM+ 组件进行了方法调用,但该组件有一个已被中止的或正在被中止的事务。 (异常来自 HRESULT:0x8004E003)
  9. JS URL编码
  10. centos 6.4 大容量磁盘分区步骤
  11. JAVA 相关资料
  12. hibernate之增删改查demo
  13. MYSQL 体系结构图-LRU
  14. 【回忆1314】第一次用AngularJS
  15. 腾讯測试project师笔试面试记录
  16. 【2017-04-25】winform公共控件、菜单和工具栏、Tab和无边框窗体制作
  17. easyui点击搜索的时候获取不要文本框里面的值的问题
  18. Ajax 跨域 异步 CORS
  19. JavaScript入门学习笔记(一)
  20. 关于破解visualsvn 我这里是版本是5.2.1

热门文章

  1. java第六周学习情况
  2. [BOM]判断是否为pc页面、是否为ios页面
  3. jmeter中返回值提取并存储。
  4. 【SQL Server】numeric——精确数字的数据类型
  5. springboot java redis 监听超时事件
  6. js apply 与 call
  7. 冰冻三尺非一日之寒,记录Java
  8. vxe-table 合并单元格
  9. 关于unity游戏的类名查找
  10. vue element tree 上移下移