LeetCode链表部分题目思路总结
2018-05-21 20:22
344 查看
反转链表
92. 反转链表IIpublic ListNode reverseBetween(ListNode head, int m, int n) { // 找到第m个节点的前一个节点 prev, 当前正在处理的节点curr(即将当前节点的下一个节点,放到prev 的下一个节点); //直到当前节点到达第n 个节点为止 if(head == null) return null; ListNode newhead = new ListNode(0); newhead.next = head; ListNode prev = newhead; int i = 1; while(prev.next != null && i < m) { // 找 第m个节点 prev = prev.next; i++; } // 此时 prev 即指向 第 m - 1 个节点, ListNode first = prev.next; ListNode second = first.next; while(first.next != null && i < n) { // 开始交换 first.next = second.next; second.next = prev.next; prev.next = second; second = first.next; i++; } return newhead.next; }206. 反转链表
public ListNode reverseList(ListNode head) { // 思路: 新建头结点,使其指向head, 交换 head 和 head 的下一个节点; //此时 前两个节点已经 逆序, 继续将head 的下一个节点放到新的头结点的下一个节点; //重复操作, 直到 head 的下一个节点为空为止; if(head == null) return null; ListNode newhead = new ListNode(0); ListNode curr; newhead.next = head; while(head.next != null) { curr = head.next; //交换两节点 head.next = curr.next; curr.next = newhead.next; newhead.next = curr; } return newhead.next; }25. k个一组翻转链表
public ListNode reverseKGroup(ListNode head, int k) { // 先遍历一次 看有多少个节点, 再 每K个一组 翻转 ListNode newhead = new ListNode(0); newhead.next = head; ListNode prev = newhead; // 记录待翻转部分的前一个节点 ListNode tmp = head; int i = 0; // 遍历 看 有多少个节点 用i 记录 原节点数 while(tmp != null) { i++; tmp = tmp.next; } while(i >= k) { // 条件成立才会翻转 for(int j = 0; j < k - 1; j++) { // head 记录当前值, after 记录head 的 下一个值 ListNode after = head.next; head.next = after.next; after.next = prev.next; prev.next = after; } prev = head; head = head.next; i -= k; } return newhead.next; }2.两数相加
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { // 两数之和, 两个链表独立操作, 需要新的链表存储结果 ListNode newhead = new ListNode(0); ListNode curr = newhead; int sum = 0; // 记录 两数之和 while(l1 != null || l2 != null) { sum /= 10; // 进位 if(l1 != null) { sum += l1.val; l1 = l1.next; } if(l2 != null) { sum += l2.val; l2 = l2.next; } curr.next = new ListNode(sum % 10); curr = curr.next; } // 判断最后一次相加之后是否有进位 if(sum > 9) curr.next = new ListNode(1); return newhead.next; }445. 两数相加 II 考虑 栈**
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; Stack<Integer> s1 = new Stack<>(); Stack<Integer> s2 = new Stack<>(); while (l1 != null) { s1.push(l1.val); l1 = l1.next; } while (l2 != null) { s2.push(l2.val); l2 = l2.next; } int sum = 0; // head的下一个结点为curNode ListNode curNode = new ListNode(0); while (!s1.isEmpty() || !s2.isEmpty()) { if (!s1.isEmpty()) sum += s1.pop(); if (!s2.isEmpty()) sum += s2.pop(); // head.val存储进制位,head.val可能为0 ListNode head = new ListNode(sum / 10); // curNode存储结果 curNode.val = sum % 10; head.next = curNode; // curNode往前移动,指向head curNode = head; // 此时sum存储的是进制位 // 下次计算需要用到 sum /= 10; } // 前导0的情况, // curNode为head的引用,可能为0 if (curNode.val == 0) curNode = curNode.next; return curNode; // 前导0的情况 // return curNode.val == 0 ? // curNode.next : curNode; }23. 合并K个排序链表
public ListNode mergeKLists(ListNode[] lists) { if(lists.length == 0) { return null; } // 控制 每隔 多少 合并一次 即 合并的 步长 for(int step = 1; step < lists.length; step *= 2) { // 控制 合并后 链表 存放的 位置 for(int i = 0; i < lists.length; i += step * 2) { if(i + step >= lists.length) break; // 索引越界 lists[i] = mergeTwoLists(lists[i], lists[i + step]); } } return lists[0]; } public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode newhead = new ListNode(-1); ListNode c = newhead; // 记录当前节点 while(l1 != null || l2 != null) { if(l2 == null || (l1 != null && l1.val < l2.val)) { // 短路 或 c.next = l1; l1 = l1.next; } else { c.next = l2; l2 = l2.next; } c = c.next; } return newhead.next; }19. 删除链表的倒数第N个节点思路: 记录倒数第N个节点的前一个节点; 为防止头结点被删除而找不到链表, 新建一个头结点,并令其下一个节点为链表的初始头结点; 双指针延迟启动, 待前一个指针到达链表的第N个节点时, 令后一个指针指向新的头结点, 并随着 前一个指针的移动而向后移动,直到前一个指针指向最后一个节点为止;
public ListNode removeNthFromEnd(ListNode head, int n) { // 删除链表的 倒数 第 n 个 节点 一趟扫描 // 防止 头结点被删除 ListNode newhead = new ListNode(-1); newhead.next = head; ListNode p1 = newhead; ListNode p2 = newhead; for(; p1 != null; p1 = p1.next, n--) { if(n < 0) { p2 = p2.next;// p2 记录待删除节点的前一个节点 } } p2.next = p2.next.next; return newhead.next; }24. 两两交换链表中的节点思路: 记录 first, second, third 其中 second 和 third 为当前正在交换的节点
public ListNode swapPairs(ListNode head) { // 当前节点 当前节点的 孩子 当前节点的 孙子 if(head == null) { return null; } ListNode newhead = new ListNode(0); ListNode first, second; newhead.next = head; ListNode current = newhead; while(current.next != null && current.next.next != null) { first = current.next; second = current.next.next; // 开始交换 first.next = second.next; second.next = first; current.next = second; // 移动当前位置 为 待交换节点的 前一个 current = first; } return newhead.next; }阅读更多
相关文章推荐
- Leetcode链表部分题目常用方法技巧总结
- [Leetcode][链表]相关题目汇总/分析/总结
- leetcode链表题目总结
- leetcode题目思路以及部分解答(一)
- leetcode题目思路以及部分解答(四)
- 【leetcode】链表常见题目总结
- hackerrank 和 leetcode的链表相关的题目的总结
- leetcode题目思路以及部分解答(三)
- leetcode题目思路以及部分解答(完)
- leetcode题目思路以及部分解答(二)
- Leetcode中的回溯法题目总结:八皇后问题; unique path问题;subsets问题
- Leetcode中的回溯法题目总结:八皇后问题; unique path问题;subsets问题
- (未完成)LeetCode 链表总结
- leetcode做题总结,题目Intersection of Two Linked Lists 2014/11/27
- LeetCode-Easy部分中标签为LinkedList的所有题目
- leetcode链表问题总结
- 链表面试笔试题目总结
- leetcode做题总结,题目Plus One 2012/04/02
- [LeetCode] Split Linked List in Parts 拆分链表成部分
- Leetcode题目总结-Math-如何判断素数?