1.指定区间内反转
题意:给定链表[1,5,6,7,4,2,9],left=2,right=5
输出:[1,4,7,6,5,2,9]
头插法
思路:遍历链表找到下标left节点的前节点preNode,当前链节点curNode为其后继节点,(curNode=preNode.next),反转curNode的下一个节点temp,使其成为preNode的后继节点,直到cur为下标为right节点为止
public NodeList reversalInLeftRight(NodeList head, int left, int right) {
NodeList dummy = new NodeList(-1);
dummy.next = head;
NodeList preNode = dummy;
//循环找到下标left节点的前继 preNode
for (int i = 0; i < left - 1; i++) {
preNode = preNode.next;
}
//下标left位置的节点为curNode,后继节点temp(需要反转)
NodeList curNode = preNode.next;
NodeList temp;
for (int i = 0; i < right - left; i++) {
temp = curNode.next;
curNode.next = temp.next;
temp.next = preNode.next;
preNode.next = temp;
}
return dummy.next;
}
穿针引线法
思路:将要反转的链表分为三部分,head-(left-1),left-right,(right+1)-末
先区间链表反转,再重新连接首尾部分...
2.两两交换链表节点
思路:定义虚拟节点dummy即不用考虑首节点的特殊情况,dummy.next = head ,
循环遍历的中止条件 dumy.next == null || demmy.next.next == null ,并交换dumy.next和
demmy.next.next 节点的位置
public NodeList swapTwo(NodeList head){
NodeList dummy = new NodeList(-1);
dummy.next = head;
//temp节点用来标记遍历的位置
NodeList temp = dummy;
while (temp.next!=null && temp.next.next!=null){
NodeList curNode = temp.next;
NodeList nextNode = temp.next.next;
//交换位置即改变指针
temp.next=nextNode;
curNode.next=nextNode.next;
nextNode.next=curNode;
temp = curNode;
}
return dummy.next;
}
3.单链表+1
思路:把链表节点的val值存放进栈,取出栈顶元素 + 1 ,循环累加并判断是否需要 进位
public NodeList addOne(NodeList head){
Stack<Integer> stack = new Stack<>();
//把链表节点的值存放进栈
while (head!=null){
stack.push(head.val);
head=head.next;
}
//carry代表进位
int carry = 0;
NodeList dummy= new NodeList(0);
int addValue = 1;
while (!stack.empty() || addValue!=0 || carry>0){
int digit = stack.empty() ? 0:stack.pop();
int sum = digit +carry + addValue;
carry= sum>=10 ? 1:0;
sum=sum>=10? sum-10:sum;
NodeList curNode = new NodeList(sum);
curNode.next = dummy.next;
dummy.next = curNode;
addValue = 0;
}
return dummy.next;
}