反转链表
public ListNode reverseList(ListNode head) {
//迭代
ListNode prev=null,next=null,curr=head;
while(curr!=null){
next=curr.next;
curr.next=prev;
prev=curr;
curr=next;
}
return prev;
}
反转链表 II
public ListNode reverseBetween(ListNode head, int left, int right) {
//头插法
ListNode dummy = new ListNode(0);
dummy.next=head;
ListNode curr=head,prev=dummy;
for(int i=0;i<left-1;i++){
prev=curr;
curr=curr.next;
}
//将当前节点的下一个节点转移到prev之后
//循环过程中prev ,curr都不变,next永远指向curr的下一个节点。
ListNode next=null;
for(int i=0;i<right-left;i++){
next=curr.next;
curr.next=next.next;
next.next=prev.next;
prev.next=next;
}
return dummy.next;
}
K 个一组翻转链表
public ListNode reverseKGroup(ListNode head, int k) {
//迭代+递归
//先处理边界
if(head==null || head.next==null){
return head;
}
ListNode curr=head;
ListNode tail=head;
for(int i=0;i<k;i++){
if(tail==null){
//不足k个,直接返回
return head;
}
tail=tail.next;
}
ListNode node = reverse(head,tail);
head.next= reverseKGroup(tail,k);
return node;
}
public ListNode reverse(ListNode head,ListNode tail){
ListNode prev=null,next=null,curr=head;
while(curr!=tail){
next=curr.next;
curr.next=prev;
prev=curr;
curr=next;
}
return prev;
}
环形链表II
/**
设head 到交点的距离为a ,环的长度为b
慢指针 走过的长度为s
快指针 走过的长度为f
f=2s;
f=s+nb;
s=nb;
那么,s再走a步,就会正好到环的入口。
*/
public ListNode detectCycle(ListNode head) {
if(head==null){
return null;
}
ListNode p=head,q=head;
while(q!=null && q.next!=null){
p=p.next;
q=q.next.next;
if(p==q){ //找到相交节点
while(head!=p){
head=head.next;
p=p.next;
}
return p;
}
}
return null;
}
删除链表的倒数第N个节点
public ListNode removeNthFromEnd(ListNode head, int n) {
//快慢指针
ListNode dummy = new ListNode();
dummy.next=head;
ListNode prev=dummy,curr=head;
for(int i=0;i<n;i++){
curr=curr.next;
}
while(curr!=null){
curr=curr.next;
prev=prev.next;
}
prev.next=prev.next.next;
return dummy.next;
}
链表求和
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int a=0;
ListNode dummy = new ListNode(0);
ListNode prev = dummy;
while(l1!=null || l2!=null || a>0){
int x=l1==null?0:l1.val;
int y=l2==null?0:l2.val;
int sum=x+y+a;
a=sum/10;
int val=sum%10;
l1=l1==null?null:l1.next;
l2=l2==null?null:l2.next;
ListNode node = new ListNode(val);
prev.next=node;
prev=prev.next;
}
return dummy.next;
}
合并K个升序链表
public ListNode mergeKLists(ListNode[] lists) {
int n = lists.length;
if(n==0){
return null;
}
if(n==1){
return lists[0];
}
int flag=n%2;
int k=n/2;
ListNode[] newList=new ListNode[k+flag];
for(int i=0,j=0;i<k;i++){
ListNode node = merge(lists[j],lists[j+1]);
newList[i]=node;
j+=2;
}
if(flag==1){
newList[k]=lists[n-1];
}
return mergeKLists(newList);
}
public ListNode merge(ListNode l1,ListNode l2){
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while(l1!=null&&l2!=null){
if(l1.val>l2.val){
curr.next=l2;
l2=l2.next;
}else{
curr.next=l1;
l1=l1.next;
}
curr=curr.next;
}
if(l1!=null){
curr.next=l1;
}
if(l2!=null){
curr.next=l2;
}
return dummy.next;
}
排序链表
public ListNode sortList(ListNode head) {
quickSort(head,null);
return head;
}
public void quickSort(ListNode head,ListNode tail){
if(head==null||head==tail){
return ;
}
ListNode prev = null;
ListNode left=head;
ListNode right=head.next;
int key=head.val;
while(right!=tail){
while(right!=null &&right!=tail && right.val>key){
right=right.next;
}
//right 和 left的下一个节点交换
if(right!=tail && left.next!=null && right!=null){
swap(left.next,right);
prev=left;
left=left.next;
right=right.next;
}
}
swap(head,left);
quickSort(head,left);
quickSort(left.next,tail);
}
public void swap(ListNode l1,ListNode l2){
int temp=l1.val;
l1.val=l2.val;
l2.val=temp;
}
回文链表
public boolean isPalindrome(ListNode head) {
ListNode fast=head,slow=head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
ListNode node = reverse(slow);
while(node!=null&&head!=null){
if(node.val!=head.val){
return false;
}
node=node.next;
head=head.next;
}
return true;
}
public ListNode reverse(ListNode head){
ListNode curr=head,next=null,prev=null;
while(curr!=null){
next=curr.next;
curr.next=prev;
prev=curr;
curr=next;
}
return prev;
}
删除排序链表中的重复元素I
public ListNode deleteDuplicates(ListNode head) {
if(head==null){
return head;
}
ListNode curr=head;
while(curr.next!=null){
if(curr.val==curr.next.val){
curr.next=curr.next.next;
}else{
curr=curr.next;
}
}
return head;
}
删除排序链表中的重复元素II
public ListNode deleteDuplicates(ListNode head) {
int preVal=101;
ListNode dummy=new ListNode(101);
dummy.next=head;
ListNode prev=dummy, curr=head;
while(curr!=null){
if(curr.val==preVal||(curr.next!=null&&curr.next.val==curr.val)){
prev.next=curr.next;
}else{
prev=curr;
}
preVal=curr.val;
curr=curr.next;
}
return dummy.next;
}
奇偶链表
public ListNode oddEvenList(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode p=new ListNode(0);
ListNode q=new ListNode(0);
ListNode pHead=p;
ListNode qHead=q;
ListNode curr=head;
int i=1;
while(curr!=null){
if(i%2==1){
p.next=curr;
p=p.next;
}else{
q.next=curr;
q=q.next;
}
i++;
curr=curr.next;
}
q.next=null;
p.next=qHead.next;
return pHead.next;
}
重排链表
leetcode-cn.com/problems/re… 没有一遍做出来,先记着
分割链表
public ListNode partition(ListNode head, int x) {
if(head==null){
return head;
}
ListNode p= new ListNode(0);
ListNode q= new ListNode(0);
ListNode qHead=q,pHead=p;
ListNode curr=head;
while(curr!=null){
if(curr.val<x){
p.next=curr;
p=p.next;
}else{
q.next=curr;
q=q.next;
}
curr=curr.next;
}
q.next=null;
p.next=qHead.next;
return pHead.next;
}