给你两个单链表的头节点?headA
?和?headB
?,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回?null
?。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3 输出:Intersected at '8'
链表A的节点个数为a? 链表B的节点个数为b? ?公共链表节点个数为c
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 双指针方法
if(headA == null || headB == null){
return null;
}
ListNode pA = headA;
ListNode pB = headB;
// 当两指针相交时,即找到两链表的相交节点
while(pA != pB){
pA = pA == null ? headB : pA.next;
pB = pB == null ?headA : pB.next;
}
return pA;
}
}
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 构造哈希集合存储链表节点
Set<ListNode> visited = new HashSet<>();
ListNode temp = headA;
// 循环将链表A的节点存入哈希集合中
while(temp != null ){
visited.add(temp);
temp = temp.next;
}
temp = headB;
// 依次判断B链表的集合是否在哈希表中
while(temp != null){
// 如果当前节点在哈希表中, 那么B链表的后面节点都在链表中
if(visited.contains(temp)){
return temp;
}
temp = temp.next;
}
return null;
}
}
采用头插法创建一个新的链表? 得到的链表即为反转之后的链表
法一 : 超出时间限制
class Solution {
public ListNode reverseList(ListNode head) {
// 新建一个链表 用头插法创建新的链表
while(head != null){
addFirst(head, head.val);
}
return head;
}
public void addFirst(ListNode head ,int data){
ListNode node = new ListNode(data);
// 让node的地址指向头部
node.next = head;
// 原来的表头节点指向node
head = node;
}
}
修改之后的代码
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;
}
}
思路:遍历链表,将链表节点中的值存入数组中,然后在使用双指针判断数组中的值是否为回文数
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
// 创建数组 存放链表中节点的值
List<Integer> list = new ArrayList<>();
// 遍历链表
ListNode currNode = head;
while(currNode != null){
list.add(currNode.val);
currNode = currNode.next;
}
// 判断数组中的值是否是回文数
int pre = 0;
int last = list.size() - 1;
while(pre <= last){
if(! list.get(pre).equals(list.get(last))){
return false;
}
pre++;
last--;
}
return true;
}
}
class Solution {
ListNode frontNode;
public boolean isPalindromeHelp(ListNode currNode){
if(currNode != null){
if(! isPalindromeHelp(currNode.next)){
return false;
}
if(currNode.val != frontNode.val){
return false;
}
frontNode = frontNode.next;
}
return true;
}
public boolean isPalindrome(ListNode head) {
frontNode = head;
return isPalindromeHelp(head);
}
}
将两个升序链表合并为一个新的?升序?链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。?
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
// 若list1 或者 list2 有其中一个为空 则返回另一个有序链表
if(list1 == null){
return list2;
}else if(list2 == null){
return list1;
}else if(list1.val < list2.val){
// 若链表1的节点小于2 则链接到链表1 然后用1的下一个节点同链表2的当前节点进行递归比较
list1.next = mergeTwoLists(list1.next, list2);
return list1;
}else {
list2.next = mergeTwoLists(list2.next, list1);
return list2;
}
}
}