题解 | #链表内指定区间反转#

链表内指定区间反转

http://www.nowcoder.com/practice/b58434e200a648c589ca2063f1faf58c

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @param m int整型 
 * @param n int整型 
 * @return ListNode类
 */
struct ListNode* ReverseList_two(struct ListNode* head, int a, int b ) 
{    
    if (a == b)
        return head;
    
    // write code here
    int i =1;
    struct ListNode *r = head;
    
    struct ListNode *s = NULL;
    struct ListNode *z = head;
    
    struct ListNode *sa = NULL;
    struct ListNode *za = NULL;
    struct ListNode *xa = NULL;
    
    struct ListNode *sb = NULL;
    struct ListNode *zb = NULL;
    struct ListNode *xb = NULL;
    
    while(z) // 遍历完整个链表
    {
        if (i == a) // 记录 a 处的 上一个 这一个 下一个
        {
            sa = s;
            za = z;
            xa = z->next;
        }
        else if (i == b) // 记录 a 处的 上一个 这一个 下一个
        {
            sb = s;
            zb = z;
            xb = z->next;
            
            if(a == 1) // 如果交换的是第一个,修改储存的返回值
                r = zb;
            break;
        }
        s = z;
        z = z->next;
        i++;
    }
    
    if (sa) // a 是第一个,没有上一个,跳过
    sa->next = zb; // a 的上一个的下一个改成 b 的这一个
    if (sb != za) // b 的上一个的下一个和 a 的这一个相同,表示 ab 连续
    sb->next = za; // b 的上一个的下一个改成 a 的这一个
    zb->next = zb != xa ? xa : za; // b 的下一个 改成 a 的下一个, 如果 a 的下一个就是 b ,表示 ab 连续, b 的下一个就是 a
    za->next = xb; // a 的下一个 改成 b 的下一个
    
    return r; // 返回链表头
}


struct ListNode* ReverseList(struct ListNode* head, int n1, int n2) 
{
    if (n1 == n2 || head == NULL || head->next == NULL)
        return head;
    
    struct ListNode* h = head;
    struct ListNode* a = NULL; // n1 -1
    struct ListNode* b = head; // n2 + 1
    struct ListNode* c = head->next; // n1
    
    int n=1;
    
    while(1)
    {
        if (n == n1-1) 
            a = b;
        if (n == n2) 
            break;
        b = c;
        c = c->next;
        n++;
    }
    b = c;
    c = a ? a->next : head;
    
    struct ListNode* s = a; 
    struct ListNode* z = c; 
    struct ListNode* x = z->next;
    
    n = 0;
    while(n++ <= n2 - n1)
    {
        x = z->next;
        z->next = s;
        s = z;
        z = x;
    }
    
    c->next = b;
    if (a)
        a->next = s;
    else
        head = s;
    
    return head; // 返回 上一个    
}

// 主函数调用 在2种方法之间切换
struct ListNode* reverseBetween(struct ListNode* head, int a, int b ) 
{    
    if (1)
    {
        return ReverseList(head, a, b); // 一个区间内整体反序
    }
    else
    {
        for (int i=0; i<=(b-a)/2; i++)
        {
            head = ReverseList_two(head, a+i, b-i); // 单独调换2个节点
        }
        return head;
    }
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
07-24 13:32
点赞 评论 收藏
分享
07-25 11:12
重庆大学 C++
既然这么缺人,为什么挂我呢
飞花断音:华为需要学历不高,但是很能干事儿,能吃苦也没怨言,愿意无偿加班,最好上有老下有小,不是独生子女,家庭条件不好,家在外地租房住,生活成本高,不会轻易跳槽,并且愿意接受低工资的奴仆任劳任怨地给任总的女儿买大别墅住
点赞 评论 收藏
分享
06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务