public static ListNode swapByNodes(ListNode head, int val1, int val2) {
if (head == null || val1 == val2) return head;
// Find nodes with val1 and val2, and their previous nodes
ListNode prev1 = null, curr1 = head;
ListNode prev2 = null, curr2 = head;
// Find first node with val1
while (curr1 != null && curr1.val != val1) {
prev1 = curr1;
curr1 = curr1.next;
}
// Find first node with val2
while (curr2 != null && curr2.val != val2) {
prev2 = curr2;
curr2 = curr2.next;
}
// If either value is not found, return original list
if (curr1 == null || curr2 == null) return head;
// If prev1 is null, curr1 is the head
if (prev1 != null) {
prev1.next = curr2;
} else {
head = curr2;
}
// If prev2 is null, curr2 is the head
if (prev2 != null) {
prev2.next = curr1;
} else {
head = curr1;
}
// Swap next pointers
ListNode temp = curr1.next;
curr1.next = curr2.next;
curr2.next = temp;
return head;
}