[25] K 个一组翻转链表
1.[6] N 字形变换2.[7] 整数反转3.[5] 最长回文子串4.[4] 寻找两个正序数组的中位数5.[3] 无重复字符的最长子串6.[2] 两数相加7.[1] 两数之和8.[8] 字符串转换整数 (atoi)9.[9] 回文数10.[10] 正则表达式匹配11.[11] 盛最多水的容器12.[12] 整数转罗马数字13.[13] 罗马数字转整数14.[14] 最长公共前缀15.[15] 三数之和16.[16] 最接近的三数之和17.[17] 电话号码的字母组合18.[18] 四数之和19.[19] 删除链表的倒数第 N 个结点20.[20] 有效的括号21.[21] 合并两个有序链表22.[22] 括号生成23.[23] 合并 K 个升序链表24.[24] 两两交换链表中的节点
25.[25] K 个一组翻转链表
26.[26] 删除有序数组中的重复项27.[27] 移除元素28.[28] 找出字符串中第一个匹配项的下标29.[29] 两数相除30.[30] 串联所有单词的子串31.[31] 下一个排列32.[32] 最长有效括号33.[33] 搜索旋转排序数组34.[34] 在排序数组中查找元素的第一个和最后一个位置35.[35] 搜索插入位置36.[36] 有效的数独37.[37] 解数独38.[38] 外观数列39.[39] 组合总和40.[40] 组合总和 II41.[41] 缺失的第一个正数42.[42] 接雨水43.[43] 字符串相乘44.[44] 通配符匹配45.[45] 跳跃游戏 II46.[46] 全排列47.[47] 全排列 II48.[48] 旋转图像49.[49] 字母异位词分组50.[50] Pow(x, n)51.[51] N 皇后52.[52] N 皇后 II53.[53] 最大子数组和54.[54] 螺旋矩阵55.[55] 跳跃游戏56.[56] 合并区间57.[57] 插入区间58.[58] 最后一个单词的长度59.[59] 螺旋矩阵 II60.[60] 排列序列61.[61] 旋转链表62.[62] 不同路径63.[63] 不同路径 II64.[64] 最小路径和65.[65] 有效数字66.[66] 加一67.[67] 二进制求和68.[68] 文本左右对齐69.[69] x 的平方根70.[70] 爬楼梯71.[71] 简化路径72.[72] 编辑距离73.[73] 矩阵置零74.[74] 搜索二维矩阵75.[75] 颜色分类76.[76] 最小覆盖子串77.[77] 组合78.[78] 子集79.[79] 单词搜索80.[80] 删除有序数组中的重复项 II/** * Definition for singly-linked list. * function ListNode(val, next) { * this.val = (val===undefined ? 0 : val) * this.next = (next===undefined ? null : next) * } */ /** * @param {ListNode} head * @param {number} k * @return {ListNode} */ var reverseKGroup = function (head, k) { if (k === 1 || k === 0 || head === null || head.next === null) { return head; } // 定义一个保护节点 let protect = new ListNode(0, null); let last = protect; let nextGroupStart = null; // 反转一串链表,前一个链表的结尾 + 反转本身 + 后一个链表的开始 while (head !== null) { // 获取最后一个节点,用于反转 let end = getEnd(head, k); // 如果到了最后不够了,保持原有顺序,直接返回即可 if (end === null) { break; } // 记录后一个链表的开始 nextGroupStart = end.next; // 反转本身,head到end反转 let reversed = reverseList(head, end); // 子链表的开头(现在的end)和上一个链表结尾结合 last.next = reversed; // 子链表的结尾(现在的head)和下一个链表开始结合 head.next = nextGroupStart; // 当前结尾下一个循环时已成上一个链表的结尾(现在的head) last = head; // 让下一个子链表开始处理吧 head = nextGroupStart; } return protect.next; } // 找到最后一个节点,返回null说明最后已经不够k个了 const getEnd = function (head, k) { let index = 1; while (head !== null) { head = head.next; if (++index === k) { return head; } } return null; // or head, depending on how you want to handle it } // 反转head-end之间的链表 const reverseList = function (head, end) { if (head === null || head.next === null) { return head; } let next = head.next; head.next = null; let p; let current = head; let nextNode = next; while (nextNode !== null && current !== end) { p = nextNode.next; nextNode.next = current; current = nextNode; nextNode = p; } return current; // could return 'head' if you want to maintain the original 'head' pointer, but it's not necessary since we know the new head will be the current node at this point anyway. (returns head if head === end or head === null) }