leetcode链表算法题实现思路
Posted yrtx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode链表算法题实现思路相关的知识,希望对你有一定的参考价值。
找出两个链表的交点(leetcode160)
一条链表遍历完之后跳转到下一条链表的头节点继续遍历。
因为当两条链表均被遍历一遍以后,第二次遍历时会同时到达节点相等的地方。如果没有相交的节点,两条链表均遍历两遍后,同时等于null,故返回null。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode l1 = headA, l2 = headB; while (l1 != l2) { l1 = (l1 == null) ? headB : l1.next; l2 = (l2 == null) ? headA : l2.next; } return l1; }
链表反转(leetcode206)
1、非递归
新建一个头结点newHeadNode,将新头节点的next赋给旧头节点的next,然后将旧头节点赋给新头节点的next并继续迭代。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseList(ListNode head) { ListNode newHeadNode = new ListNode(-1); while(head != null) { ListNode next = head.next; head.next = newHeadNode.next; newHeadNode.next = head; head = next; } return newHeadNode.next; } }
//更简单的办法
class Solution {
public ListNode reverseList(ListNode head) {
ListNode newHead = null;
while (head != null) {
ListNode nextNode = head.next;
head.next = newHead;
newHead = head;
head = nextNode;
}
return newHead;
}
}
2、递归
进入递归直到head.next == null,然后回到上一层,此时newHeadNode是最后一个节点,head是倒数第二个节点。将最后一个节点的next指向倒数第二个节点,再将倒数第二个节点的next置空,以防止链表反转后最后一个节点的next不为null。依此类推反复执行head.next.next = head; head.next = null;
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseList(ListNode head) { if(head == null || head.next == null) { return head; } ListNode newHeadNode = reverseList(head.next); head.next.next = head; head.next = null; return newHeadNode; } }
归并两个有序链表(leetcoed21)
1、递归
比较两个链表的值的大小,若l1.val < l2.val则将l2向后迭代,直至l1或l2为null并返回另一个不为null的节点然后开始逐层拼接。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if(l1 == null) return l2; if(l2 == null) return l1; if(l1.val < l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; }else{ l2.next = mergeTwoLists(l1, l2.next); return l2; } } }
2、非递归
创建一个新的链表并将两条链表逐一添加到新链表中。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode newHeadNode = new ListNode(-1); ListNode prev = newHeadNode; while(l1 != null && l2 != null) { if(l1.val < l2.val) { prev.next = l1; l1 = l1.next; }else{ prev.next = l2; l2 = l2.next; } prev = prev.next; } prev.next = l1 == null ? l2 : l1;//添加最后一个节点 return newHeadNode.next; } }
删除排序链表中的重复元素(leetcode83)
1、非递归
判断当前链表节点的值与后一个链表的值是否相等,若相同,则将后一个节点的next指向当前节点的next。若不同,则向后迭代直至边界。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode deleteDuplicates(ListNode head) { ListNode current = head; while (current != null && current.next != null) { if (current.next.val == current.val) { current.next = current.next.next; } else { current = current.next; } } return head; } }
2、递归
递归到最后一层开始返回,如果head.val == head.next.val 则一直返回最后一个节点,如果不同则开始拼接。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode deleteDuplicates(ListNode head) { if(head == null || head.next == null) return head; head.next = deleteDuplicates(head.next); return head.next.val == head.val ? head.next : head; } }
删除链表的倒数第n个节点(leetcode19)
1、两次循环
先遍历获取链表长度,再遍历找到节点的前一个位置。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode curr = new ListNode(-1); curr.next = head; ListNode first = head; int length = 0; while(first != null) { first = first.next; length++; } length -= n; first = curr; while(length-- > 0) { first = first.next; } first.next = first.next.next; return curr.next; } }
2、一次循环
创建两个节点一个指向head,一个指向距head节点 n 个节点的节点,即n+1个节点。当第n+1个节点为null时,指向head的节点刚好指向倒数第n个位置。
public ListNode removeNthFromEnd(ListNode head, int n) { ListNode fast = head; while (n-- > 0) { fast = fast.next; } if (fast == null) return head.next; ListNode slow = head; while (fast.next != null) { fast = fast.next; slow = slow.next; } slow.next = slow.next.next; return head; }
交换链表中的相邻结点(leetcode24)
1、递归
递归至尾节点,然后将最后一个节点的next指向head.next,head指向next.next。完成交换。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode swapPairs(ListNode head) { if(head == null || head.next == null) { return head; } ListNode next = head.next; head.next = swapPairs(next.next); next.next = head; return next; } }
2、非递归
思路如上,从头开始俩俩交换。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode swapPairs(ListNode head) { ListNode pre = new ListNode(0); pre.next = head; ListNode temp = pre; while(temp.next != null && temp.next.next != null) { ListNode start = temp.next; ListNode end = temp.next.next; temp.next = end; start.next = end.next; end.next = start; temp = start; } return pre.next; } }
两数相加 II(leetcode445)
双栈法。即利用两个栈进行运算并拼接链表。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { Stack<Integer> stack1 = buildStack(l1); Stack<Integer> stack2 = buildStack(l2); ListNode head = new ListNode(-1); int carry = 0; while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) { int x = stack1.isEmpty() ? 0 : stack1.pop(); int y = stack2.isEmpty() ? 0 : stack2.pop(); int sum = x + y + carry; ListNode node = new ListNode(sum % 10); node.next = head.next; head.next = node; carry = sum / 10; } return head.next; } private Stack<Integer> buildStack(ListNode l) { Stack<Integer> stack = new Stack<>(); while (l != null) { stack.push(l.val); l = l.next; } return stack; } }
回文链表(leetcode)
找到中间点,分割,反转,比较。
public boolean isPalindrome(ListNode head) { if (head == null || head.next == null) return true; ListNode slow = head, fast = head.next; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } if (fast != null) slow = slow.next; // 偶数节点,让 slow 指向下一个节点 cut(head, slow); // 切成两个链表 return isEqual(head, reverse(slow)); } private void cut(ListNode head, ListNode cutNode) { while (head.next != cutNode) { head = head.next; } head.next = null; } private ListNode reverse(ListNode head) { ListNode newHead = null; while (head != null) { ListNode nextNode = head.next; head.next = newHead; newHead = head; head = nextNode; } return newHead; } private boolean isEqual(ListNode l1, ListNode l2) { while (l1 != null && l2 != null) { if (l1.val != l2.val) return false; l1 = l1.next; l2 = l2.next; } return true; }
分割链表(leetcode725)
先遍历确定链表的长度,然后和k值进行运算比较确定每个分割链表的大小,最后进行遍历填充。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode[] splitListToParts(ListNode root, int k) { int N = 0; ListNode cur = root; while (cur != null) { N++; cur = cur.next; } int mod = N % k; int size = N / k; ListNode[] ret = new ListNode[k]; cur = root; for (int i = 0; cur != null && i < k; i++) { ret[i] = cur; int curSize = size + (mod-- > 0 ? 1 : 0); for (int j = 0; j < curSize - 1; j++) { cur = cur.next; } ListNode next = cur.next; cur.next = null; cur = next; } return ret; } }
奇偶链表(leetcode328)
新建一个奇数位置的迭代指针odd和一个偶数位置迭代指针even,然后第一个.next = 第三个;第二个.next = 第四个;并向后迭代最后把偶数头部指向奇数末尾odd。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode oddEvenList(ListNode head) { if(head == null) { return head; } ListNode odd = head, even = head.next, evenHead = even; while(even != null && even.next != null) { odd.next = odd.next.next; odd = odd.next; even.next = even.next.next; even = even.next; } odd.next = evenHead; return head; } }
以上是关于leetcode链表算法题实现思路的主要内容,如果未能解决你的问题,请参考以下文章