1.1 头插法:将区间内遍历到的结点插入到起始处之前。
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
// 将pre移动到区间的前一位,pre.next指向每次遍历到的需要插入到起始处的结点
for (int i = 0; i < left - 1; i++) {
pre = pre.next;
}
// cur负责遍历
ListNode cur = pre.next;
// next存储遍历到的结点
ListNode next;
for (int i = 0; i < right - left; i++) {
//存储遍历到的结点cur.next
next = cur.next;
//将cur.next向后移动,下次循环继续遍历
cur.next = next.next;
//让遍历到的结点指向起始处的结点
next.next = pre.next;
//pre指向新的起始处
pre.next = next;
}
return dummyNode.next;
}
1.2 穿针引线法:找到需要裁切的地方,将子链表整体反转,然后再缝到切开的地方。
public ListNode reverseBetween(ListNode head, int left, int right){
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
// 找 left 结点的前一个结点
for (int i = 0; i < left - 1; i++) {
pre = pre.next;
}
// 找 right 结点
ListNode rightNode = pre;
for (int i = 0; i < right - left + 1; i++) {
rightNode = rightNode.next;
}
// 切割子链表
ListNode leftNode = pre.next;
ListNode succ = rightNode.next;
rightNode.next = null;
// 反转链表
reverseList(leftNode);
// 拼接
pre.next = rightNode;
leftNode.next = succ;
return dummyNode.next;
}
// 反转链表算法
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while(curr != null){
ListNode next = curr.next;
// 这里对链表的结构进行了更改
// 所以不需要返回值,但是上面的leftNode结构已经更改了
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}
捋清楚成对交换结点时的指针指向即可。
public ListNode swapPairs(ListNode head) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode temp = dummyHead;
while (temp.next != null && temp.next.next != null) {
ListNode node1 = temp.next;
ListNode node2 = temp.next.next;
temp.next = node2;
node1.next = node2.next;
node2.next = node1;
temp = node1;
}
return dummyHead.next;
}
3.1 基于栈实现。
public ListNode plusOne(ListNode head) {
Stack<Integer> stack = new Stack();
while (head != null) {
stack.push(head.val);
head = head.next;
}
int carry = 0;
ListNode dummy = new ListNode(0);
// 本题要加1,所以设置了adder为1
int adder = 1;
while (!stack.empty() || carry > 0) {
int digit = stack.empty() ? 0 : stack.pop();
int sum = digit + carry + adder;
carry = sum / 10;
sum = sum % 10;
ListNode cur = new ListNode(sum);
cur.next = dummy.next;
dummy.next = cur;
//加一次以后adder就可以置0了
adder = 0;
}
return dummy.next;
}
3.2 链表反转实现。【持续更新】
4.1 栈实现:栈顶都是两个数的最低位,所以可以一起弹出。
public ListNode addInListByStack(ListNode head1, listNode head2) {
Stack<ListNode> stack1 = new Stack<>();
Stack<ListNode> stack2 = new Stack<>();
while (head1 != null) {
stack1.push(head1);
head1 = head1.next;
}
while (head2 != null) {
stack2.push(head2);
head2 = head2.next;
}
ListNode newHead = new ListNode(-1);
int carry = 0;
while (!stack1.empty() || !stack2.empty() || carry != 0) {
ListNode a = new ListNode(0);
ListNode b = new ListNode(0);
if (!stack1.empty()) {
a = stack1.pop();
}
if (!stack2.empty()) {
b = stack2.pop();
}
int get_sum = a.val + b.val + carry;
int ans = get_sum % 10;
carry = get_sum / 10;
ListNode cur = new ListNode(ans);
cur.next = newHead.next;
newHead.next = cur;
}
return newHead.next;
}
4.2 链表反转实现。
public class Solution {
public ListNode addInList(ListNode head1, ListNode head2) {
head1 = reverse(head1);
head2 = reverse(head2);
ListNode head = new ListNode(-1);
ListNode cur = head;
int carry = 0;
while (head1 != null || head2 != null || carry != 0) {
int sum = carry;
if (head1 != null) {
sum += head1.val;
head1 = head1.next;
}
if (head2 != null) {
sum != head2.val;
head2 = head2.next;
}
cur.next = new ListNode(sum % 10);
carry = sum / 10;
cur = cur.next;
}
return reverse(head.next);
}
// 链表反转方法
public ListNode reverse(ListNode head){
ListNode cur = head;
ListNode pre = null;
while (cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
}
4.3 链表减法:【持续更新】。
书接上回,可以使用栈或者链表反转来做。
public boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) {
return true;
}
ListNode slow = head, fast = head;
ListNode pre = head, prepre = null;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
pre.next = prepre;
prepre = pre;
}
if (fast != null) {
slow = slow.next;
}
while (pre != null && slow != null) {
if (pre.val != slow.val) {
return false;
}
pre = pre.next;
slow = slow.next;
}
return true;
}
如果对您有帮助,请点赞关注支持我,谢谢!❤
如有错误或者不足之处,敬请指正!❤