当前位置: 首页 > news >正文

衡水哪儿做wap网站成品短视频app下载有哪些软件

衡水哪儿做wap网站,成品短视频app下载有哪些软件,常用网站开发工具,网站建设流程精英前置知识 数据结构-链表反转部分链表算法题的手写栈使用 难度: 初阶:使用容器, 难度中等。进阶:纯coding修改指针 ,难度中等,虽然leetcode是困难题。不过更加注重细节。 题目:反转 k 组中的…

前置知识

  • 数据结构-链表
  • 反转部分链表
  • 算法题的手写栈使用

难度:

  • 初阶:使用容器, 难度中等。
  • 进阶:纯coding修改指针 ,难度中等,虽然leetcode是困难题。不过更加注重细节。

题目:反转 k 组中的节点

给定一个单链表的头节点head, 实现一个调整单链表的函数, 要求每k个节点之间逆序, 如果不够k个节点,那么不调整。

输入: head = [1,2,3,4,5], k = 2
输出: [2,1,4,3,5]
其中, [1,2]为一组,[3,4]为一组,5不足则不调整。
[1,2]逆序[2,1], [3,4]逆序[4,3]

细节处理:

  1. 第一组逆转时, 整个链表的头节点从原来的1改成了2, 涉及换头逻辑处理。 题目也要求返回新链表的头节点。需要处理。
  2. 1 <= k <= n <= 5000, 力扣给定范围。考虑特殊数据的处理。 k<2的链表是不需要处理的。因为k<=0视为无效,k==1是对单个节点进行逆序,没有意义。因此,排除了1的处理。
  3. 由于我们逆序的是某个链表的局部, 这就涉及对整体链表与局部修改连接的维护。具体看code。

解法1:使用栈这个容器

事先声明, 这里采用的是全局静态数组充当栈的写法, 读者可根据需求自行改写成Java,C++内置栈的写法。
讲解在代码下面。

//提交代码, 将类名ReverseGroup -> Solution
public class ReverseGroup {//题目给定k最大5000,那么5001肯定足够了。 实测1201也可以public static int MAX = 5001;//类静态数组充当栈public static ListNode[] stack = new ListNode[MAX];//记录栈的大小, size == 0意味栈空。public static int size;//主方法public ListNode reverseKGroup(ListNode head, int k) {//排除无效数据if(k < 2) {return head;}//重置size,防止被上组数据污染, 实现空间复用。size = 0;return f(head,k);//调用辅助方法}/*** * @param head 原链表头节点* @param k 每k个逆序* @return 返回新链表的头节点*/private ListNode f(ListNode head, int k) {ListNode newHead = head, cur = head, prev = null, next = null;while(cur != null) {next = cur.next;//压栈stack[size++] = cur;while(size==k) {//满足则执行逆序prev = reversePart(prev,next);//调整newHead为修改后链表的头节点。newHead = newHead == head?cur: newHead;}cur = next;}return newHead;}/*** * @param left 修改局部链表头节点的前驱* @param right	修改局部链表尾节点的后继* @return 返回下一对修改局部链表的前驱节点。*/private ListNode reversePart(ListNode left, ListNode right) {ListNode cur = stack[--size];if(left != null) {left.next = cur;}ListNode next = null;while(size > 0) {next = stack[--size];cur.next = next;cur = next;}cur.next = right;return cur;}
}
private ListNode f(ListNode head, int k) {ListNode newHead = head, cur = head, prev = 					null, next = null;while(cur != null) {next = cur.next;//压栈stack[size++] = cur;while(size==k) {//满足则执行逆序prev = reversePart(prev,next);//调整newHead为修改后链表的头节点。newHead = newHead == head?cur: newHead;}cur = next;}return newHead;}
  1. newHead:修改后链表的新头节点。从逻辑上有两种可能, 如果发生第一组的调整, 那么newHead一定不是原先的head, 那么你可以看到内层while循环内部newHead = newHead == head?cur: newHead;, 就是第一组逆序, newHead应该指向cur的节点。
    比如,[1,2,3,4,5], k=2, cur在应该指向2这个节点,刚好第一组逆序[2,1,3,4,5], cur指向节点就是修改后的新头节点。
  2. cur指向的就是当前要入栈的节点,压栈 stack[size++] = cur;cur还充当外部循环遍历链表的作用。
  3. next: 修改局部链表尾节点的后继, 当发生逆序过程时,next指向那一组尾节点的后继。比如[1,2]逆序时,next指向2的后继3。因为只有进入循环, next始终是cur.next。
  4. prev:修改局部链表头节点的前驱, 第一组修改时为null,所以初始化为null,后续组的前驱节点交给reversePart函数返回值维护。
  5. size==k,当前栈大小满足k时需要逆序这组。reversePart(prev,next)这个函数,接受这组的前驱和后继,比如[1,2,3,4,5], k=2, 先逆序[1,2],就需要传入null前驱,3后继。因为函数内部逻辑要维护局部修改和整体的连接。reversePart(prev,next),这个函数还需要返回下一组(如果不存在那么用不上了)的前驱节点。比如[2,1,3,4,5]完成了1,2之间的逆序,那么还要返回下一对[3,4]的前驱1。那么下一次调用就传入1前驱和5后继来逆序3,4。
private ListNode reversePart(ListNode left, ListNode right) {ListNode cur = stack[--size];if(left != null) {left.next = cur;}ListNode next = null;while(size > 0) {next = stack[--size];cur.next = next;cur = next;}cur.next = right;return cur;}
  • 先出栈, 出栈节点就是局部链表的头结点, left(不为空)连接该节点。
  • 循环出栈连接逻辑
  • 最后出栈的结点连接后继right。
  • 返回下一组的前驱节点就是当前cur的节点。自行画图理解。
    在这里插入图片描述
    时间复杂度: O ( n ) O(n) O(n)
    空间复杂度: O ( k ) O(k) O(k)

解法2:原链表调整

//提交时,注意修改函数名public ListNode reverseKGroup1(ListNode head, int k) {// 特殊输入判断if (k < 2) {return head;}ListNode cur = head, start = null, prev = null, next = null;int count = 1;// 计数变量。while (cur != null) {next = cur.next;// 后继始终跟着循环更新。if (count == k) {start = prev == null ? head : prev.next;// 获得当前逆序对开始节点head = prev == null ? cur : head;// 第一组逆序需要修改头节点reversePart2(prev, start, cur, next);// (prev,next),[start,end]prev = start;// 更新前驱范围count = 0;// 重置}++count;// 自增cur = next;// cur跟着next。}return head;// head指向的更新后的头节点或者原先的头节点。}private void reversePart2(ListNode left, ListNode start, ListNode end,ListNode right) {//反转部分链表一样的逻辑 ListNode prev = start,next = null, cur = start.next;while(cur != right){next = cur.next;cur.next = prev;prev = cur;cur = next;}if(left!=null) {left.next = end;}start.next = right;}

在这里插入图片描述
每日两题结束。

http://www.ds6.com.cn/news/32887.html

相关文章:

  • 网站开发需求分析报告网站注册域名
  • 营销型网站建设概述网站交易平台
  • 成都网站建设科技公司谷歌chrome安卓版
  • 做博客网站怎么赚钱海洋seo
  • 深圳汇网网站建设二级域名注册
  • 外包网站该怎么做帐新闻发布会新闻通稿
  • 网站页面怎么做识别二维码竞价排名推广
  • 东莞网站建设兼职seo优化技术
  • wordpress 本地上传服务器seo优化工具有哪些
  • 一级a做愛视频网站博客网
  • 网站建设跟网站结构福州关键词排名软件
  • 如何在网站后台备份数据库宁德市人力资源和社会保障局
  • 做网站邯郸成全视频免费观看在线看
  • 做贸易选哪家网站百度官方app下载
  • 深圳网博网站建设网站推广的方法有哪些?
  • 二手表网站石家庄网络营销
  • 制作网站美国站外推广网站
  • 做代练网站能备案seo发包软件
  • 不是固定ip如何做网站推广计划书怎么写
  • 做网站的话 java和c游戏推广员是违法的吗
  • 做网站如何与腾讯合作免费网站推广工具
  • 嘉兴制作网站机构百度推广登录首页官网
  • 企业网站小程序源码销售营销方案100例
  • 网站与网站之间做的好坏对比南昌seo服务
  • 丽水建设部门网站网络黄页推广大全
  • vip域名做网站好不好青岛seo关键词
  • 贵阳网络推广哪家靠谱seo外包一共多少钱
  • 企业网站制作公司推荐南宁seo咨询
  • 做网站还能挣钱吗竞价销售是什么意思
  • 网站建设大概好多钱郑州全域静态管理