leetcode 链表相关算法题

package linkedlist;


import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;


class ListNode{
int val;
ListNode next;
ListNode(int x){
this.val=x;
}
}




public class AddTwoNumber {


public static void main(String[] args) {

ListNode l1=new ListNode(1);
ListNode l2=new ListNode(2);
ListNode l3=new ListNode(3);
ListNode l4=new ListNode(3);
ListNode l5=new ListNode(4);
ListNode l6=new ListNode(4);
ListNode l7=new ListNode(5);

l1.next=l2;
l2.next=l3;
l3.next=l4;
l4.next=l5;
l5.next=l6;
l6.next=l7;

printcontent(l1);
ListNode ln=deleteDuplicates3(l1);
printcontent(ln);
}

public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode c1 = l1;
        ListNode c2 = l2;
        ListNode sentinel = new ListNode(0);
        ListNode d = sentinel;
        int sum = 0;
        while (c1 != null || c2 != null) {
            sum /= 10;
            if (c1 != null) {
                sum += c1.val;
                c1 = c1.next;
            }
            if (c2 != null) {
                sum += c2.val;
                c2 = c2.next;
            }
            d.next = new ListNode(sum % 10);
            d = d.next;
        }
        if (sum / 10 == 1)
            d.next = new ListNode(1);
        return sentinel.next;
    }

//print ListNode
public static void printcontent(ListNode ln){
StringBuffer sb=new StringBuffer();
sb.setLength(0);
while(ln.next!=null){
sb.append(ln.val+"->");
ln=ln.next;
}
sb.append(ln.val);
System.out.println(sb.toString());
}

//get link list size
public static int getsize(ListNode ln){
int count=1;
while(ln.next!=null){
count++;
ln=ln.next;
}
return count;
}

//reverse link list
public static ListNode reverse(ListNode head){
ListNode newhead=null;
while(head!=null){
ListNode tmp=head.next;
head.next=newhead;
newhead=head;
head=tmp;
}
return newhead;
}

//if has circle
public static boolean hasCircle(ListNode head){
if(head == null){
return false;
}
ListNode walker=head;
ListNode runner=head;
while(runner.next!=null && runner.next.next!=null){
walker=walker.next;
runner=runner.next.next;
if(walker==runner){
return true;
}
}
return false;
}

public static ListNode detectCycle(ListNode head){
HashSet nodes=new HashSet();
ListNode current=head;
while(current!=null){
if(nodes.contains(current)){
return current;
}
nodes.add(current);
current=current.next;
}
return null;
}

public static boolean hasCircle1(ListNode head){
ListNode p=head;
ListNode pre=head;
while(p!=null && p.next!=null){
if(p.next==head){
return true;
}
p=p.next;
pre.next=head;
pre=p;
}
return false;
}
//delete node
public static void deleteNode(ListNode del){
if(del.next==null){
return;
}
del.val=del.next.val;
ListNode temp=del.next;
del.next=del.next.next;
}

//merge two sorted listNode
public static ListNode mergeTwolists(ListNode l1,ListNode l2){
if(l1==null){
return l2;
}
if(l2==null){
return l1;
}
ListNode mergehead;
if(l1.val<l2.val){
mergehead=l1;
mergehead.next=mergeTwolists(l1.next,l2);
}else{
mergehead=l2;
mergehead.next=mergeTwolists(l1,l2.next);
}
return mergehead;
}
//merge sort
public static ListNode merge(ListNode l1,ListNode l2){
ListNode l=new ListNode(0);
ListNode p=l;
while(l1!=null&&l2!=null){
if(l1.val<l2.val){
p.next=l1;
l1=l1.next;
}else{
p.next=l2;
l2=l2.next;
}
p=p.next;
}
if(l1!=null){
p.next=l1;
}
if(l2!=null){
p.next=l2;
}
return l.next;
}
public static ListNode sortList(ListNode head){
if(head == null || head.next==null){
return head;
}
//step 1 cut the list to two halves
ListNode prev=null;
ListNode slow=head;
ListNode fast=head;
while(fast!=null&&fast.next!=null){
prev=slow;
slow=slow.next;
fast=fast.next.next;
}
prev.next=null;
//step 2 sort each half
ListNode l1=sortList(head);
ListNode l2=sortList(slow);
//step 3 merge l1 and l2
//return merge(l1,l2);
return mergeTwolists(l1,l2);
}
//qiuck sort
public static ListNode sortlist1(ListNode head){
if(head==null||head.next==null){
return head;
}
ListNode dummy1=new ListNode(0);
ListNode dummy2=new ListNode(0);
ListNode prev1=dummy1;
ListNode prev2=dummy2;
ListNode node=head.next;
ListNode prev=head;
while(node!=null){
if(node.val<head.val){
prev1.next=node;
prev1=prev1.next;
}else if(node.val>head.val){
prev2.next=node;
prev2=prev2.next;
}else{
prev.next=node;
prev=prev.next;
}
node=node.next;
}
prev1.next=prev2.next=prev.next=null;
dummy1.next=sortlist1(dummy1.next);
dummy2.next=sortlist1(dummy2.next);
prev1=dummy1;
while(prev1.next!=null){
prev1=prev1.next;
}
prev1.next=head;
prev.next=dummy2.next;
return dummy1.next;
}

//get length
public static int getlength(ListNode l){
        int i=0;
while(l!=null){
i++;
l=l.next;
}
return i;
}

//find intersection node
public static ListNode getintersectionNode(ListNode l1,ListNode l2){
int len1=getlength(l1);
int len2=getlength(l2);
while(len1>len2){
l1=l1.next;
len1--;
}
while(len2>len1){
l2=l2.next;
len2--;
}
while(l1!=l2){
l1=l1.next;
l2=l2.next;
}
return l1;


public static ListNode getintersectionNode1(ListNode l1,ListNode l2){
//boundary check
if(l1==null || l2==null){
return null;
}
ListNode a=l1;
ListNode b=l2;
//if a,b have different length,then we will stop the loop after second iteration
while(a!=b){
//for the end of first iteration, we just reset the pointer to the heap of another linkedlist
a=a==null? l1:a.next;
b=b==null? l2:b.next;
}
return a;
}

//merge k lists
public static ListNode mergeKLists(List<ListNode> lists){
if(lists==null || lists.size()==0){
return null;
}
PriorityQueue<ListNode> queue=new PriorityQueue<ListNode>(lists.size(),new Comparator<ListNode>(){
public int compare(ListNode o1,ListNode o2){
if(o1.val<o2.val){
return -1;
}else if(o1.val==o2.val){
return 0;
}else{
return 1;
}
}
});
ListNode dummy=new ListNode(0);
ListNode tail=dummy;
for(ListNode node:lists){
if(node!=null){
queue.add(node);
}
}
while(!queue.isEmpty()){
tail.next=queue.poll();
tail=tail.next;
if(tail.next!=null){
queue.add(tail.next);
}
}
return dummy.next;
}

public static ListNode mergeKlists1(List<ListNode> lists){
if(lists.size()==0){
return null;
}
if(lists.size()==1){
return lists.get(0);
}
if(lists.size()==2){
return mergeTwolists(lists.get(0),lists.get(1));
}
return mergeTwolists(mergeKlists1(lists.subList(0, lists.size()/2)),mergeKlists1(lists.subList(lists.size()/2, lists.size())));
}
//there exists some questions about heap, the result is wrong
public static ListNode mergeKlists2(List<ListNode> lists){
Heap h=new Heap(lists);
h.creatMinHeap();
ListNode result=null;
if(h.getlen()!=0){
result=h.getHeap();
}else{
return result;
}
ListNode temp=result;
while(h.getlen()!=0 && temp!=null){
temp.next=h.getHeap();
temp=temp.next;
}
return result;
}

//remove Nth node from end of list
public static ListNode getListNoderemove(ListNode head, int n){
ListNode start=new ListNode(0);
ListNode slow=start;
ListNode fast=start;
slow.next=head;

//move fast in front so that the gap between slow and fast becomes n
for(int i=1;i<=n+1;i++){
fast=fast.next;
}
//move fast to the end,maintaining the gap
while(fast!=null){
slow=slow.next;
fast=fast.next;
}
//skip the desired node
slow.next=slow.next.next;
return start.next;
}

//sort listnode by insert method
public static ListNode insertsort(ListNode head){
if(head==null){
return head;
}
//new start of the sorted list
ListNode helper=new ListNode(0);
//the node will be inserted
ListNode cur=head;
//insert ndoe between pre and pre.next
ListNode pre=helper;
//the next node will be inserted
ListNode next=null;
//not the end of input list
while(cur!=null){
next=cur.next;
//find the right place to insert
while(pre.next!=null && pre.next.val<cur.val){
pre=pre.next;
}
//insert between pre and pre.next
cur.next=pre.next;
pre.next=cur;
pre=helper;
cur=next;
}
return helper.next;
}

public static boolean isPalindeomr(ListNode head){
if(head==null || head.next==null){
return true;
}
ListNode start=new ListNode(0);
start.next=head;
ListNode firstHalfStart =head;
ListNode secondHalfStart = head;
ListNode fast=head;
//traverse to mid mode and reverse the first half of the Linkedlist in the same run
while(fast.next!=null && fast.next.next!=null){
fast=fast.next.next;

start.next=secondHalfStart.next;
secondHalfStart.next=secondHalfStart.next.next;
start.next.next=firstHalfStart;

firstHalfStart = start.next;
}
//offset for odd number of elements
//as the mid node is common to both halves, this should be shipped
if(fast.next==null){
firstHalfStart = firstHalfStart.next;
}
//at the end of the previous loop,secondHalfStart pointer is still stuck on the end of the first half
//shift it by one to take it to the start of the SecondHalf
secondHalfStart = secondHalfStart.next;

while(secondHalfStart!=null){
if(firstHalfStart.val!=secondHalfStart.val){
return false;
}
secondHalfStart = secondHalfStart.next;
firstHalfStart = firstHalfStart.next;
}
return true;
}

//remove duplicate node
public static ListNode deleteDuplicates(ListNode head){
ListNode dummy=new ListNode(0);
dummy.next=head;
ArrayList<Integer> al=new ArrayList<Integer>();
while(head!=null){
if(!al.contains(head.val)){
al.add(head.val);

}else{
head.next=head.next.next;
}
head=head.next;
}
return dummy.next;
}

public static ListNode deleteDuplicates1(ListNode head){
ListNode list=head;
while(list!=null){
if(list.next==null){
break;
}
if(list.val==list.next.val){
list.next=list.next.next;
}else{
list=list.next;
}
}
return head;
}

public static ListNode deleteDuplicates2(ListNode head){
if(head==null || head.next==null){
return head;
}
head.next=deleteDuplicates2(head.next);
return head.val==head.next.val?head.next:head;
}
//remove nodes that have duplicate numbers
public static ListNode deleteDuplicates3(ListNode head){
if(head==null||head.next==null){
return head;
}
//use two pointer,slow-track the node before the dup nodes
//fast-to find last node of dups
ListNode dummy=new ListNode(0);
ListNode fast=head;
ListNode slow=dummy;
slow.next=fast;
while(fast!=null){
while(fast.next!=null && fast.val==fast.next.val){
fast=fast.next;
}
if(slow.next!=fast){
slow.next=fast.next;
fast=slow.next;
}else{
slow=slow.next;
fast=fast.next;
}
}
return dummy.next;
}

//resort list
public static void resortlist(ListNode head){
if(head==null || head.next==null){
return;
}
//find the middle of the list
ListNode p1=head;
ListNode p2=head;
while(p2.next!=null && p2.next.next!=null){
p1=p1.next;
p2=p2.next.next;
}
//reverse the half after middle 1->2->3->4->5->6 1->2->3->6->5->4
ListNode premiddle=p1;
ListNode preCurrent=p1.next;
while(preCurrent.next!=null){
ListNode current=preCurrent.next;
preCurrent.next=current.next;
current.next=premiddle.next;
premiddle.next=current;
}
//start reorder one by one 1->2->3->4->5->6 1->6->2->5->3->4
p1=head;
p2=premiddle.next;
while(p1!=premiddle){
premiddle.next=p2.next;
p2.next=p1.next;
p1.next=p2;
p1=p2.next;
p2=premiddle.next;
}
}

public static ListNode recordNodes1(ListNode head){
if(head==null||head.next==null){
return head;
}
Deque<ListNode> stack=new ArrayDeque<ListNode>();
ListNode ptr=head;
while(ptr!=null){
stack.push(ptr);
ptr=ptr.next;
}
int cnt=(stack.size()-1)/2;
ptr=head;
while(cnt-->0){
ListNode top=stack.pop();
ListNode tmp=ptr.next;
ptr.next=top;
top.next=tmp;
ptr=tmp;
}
stack.pop().next=null;
return head;
}

//swap nodes in pairs
public static ListNode SwapNodes(ListNode head){
ListNode start=new ListNode(0);
start.next=head;
ListNode current=start;
while((current.next!=null) && (current.next.next!=null)){
ListNode first=current.next;
ListNode second=current.next.next;
first.next=second.next;
current.next=second;
current.next.next=first;
current=current.next.next;
}
return start.next;
}

//odd even linked list
public static ListNode getoddlist(ListNode head){
if(head==null || head.next==null){
return head;
}

ListNode p1=head;
ListNode p2=head.next;
ListNode p2start=p2;
while(p1!=null){
p1.next=p1.next.next;
p1=p1.next;
}
// while(p2.next!=null){
// p2.next=p2.next.next;
// p2=p2.next;
// }
//p1.next=p2start;
return head;
}

public static ListNode oddEvevList(ListNode head){
if(head==null){
return head;
}
ListNode odd=head;
ListNode even=head.next;
ListNode evenhead=even;
while(even!=null && even.next!=null){
odd.next=odd.next.next;
even.next=even.next.next;
odd=odd.next;
even=even.next;
}
odd.next=evenhead;
return head;


public static ListNode oddEvenList1(ListNode head){
if(head==null||head.next==null||head.next.next==null){
return head;
}
ListNode odd=head;
ListNode even=head.next;
ListNode even1=head.next;
while(even!=null && even.next!=null){
odd.next=even.next;
odd=odd.next;
even.next=odd.next;
even=even.next;
}
odd.next=even1;
return head;
}


//remove linked list element
public static ListNode removenode(ListNode head,int val){
if(head==null){
return head;
}
ListNode fakehead=new ListNode(0);
fakehead.next=head;
ListNode curr=head;
ListNode prev=fakehead;
while(curr!=null){
if(curr.val==val){
prev.next=curr.next;
}else{
prev=prev.next;
}
curr=curr.next;
}
return fakehead.next;
}

public static ListNode removeElements1(ListNode head,int val){
while(head!=null && head.val==val){
head=head.next;
}
ListNode cur=head;
while(cur!=null && cur.next!=null){
if(cur.next.val==val){
cur.next=cur.next.next;
}else{
cur=cur.next;
}

}
return head;
}

//rotate right
public static ListNode rotateright(ListNode head,int n){
if(head==null||head.next==null){
return head;
}
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode fast=dummy;
ListNode slow=dummy;
//get length of ListNode
int i=0;
for(i=0;fast.next!=null;i++){
fast=fast.next;
}
// while(head!=null){
// i++;
// head=head.next;
// }
//get the i-n%i th node
for(int j=i-n%i;j>0;j--){
slow=slow.next;
}
//do the rotate
fast.next=dummy.next;
dummy.next=slow.next;
slow.next=null;
return dummy.next; 
}

//reverse linked list from position m to n
public static ListNode reverseinrange(ListNode head,int m,int n){
if(head==null){
return head;
}
ListNode dummy=new ListNode(0);
dummy.next=head;
//pre refer to m-1 th node
ListNode pre=dummy;
for(int i=0;i<m-1;i++){
pre=pre.next;
}
//start refer to m th node
ListNode start=pre.next;
// a pointer to a node that will be reversed
ListNode then=start.next;
for(int i=0;i<n-m;i++){
start.next=then.next;
then.next=pre.next;
pre.next=then;
then=start.next;
}
return dummy.next;
}
//partition list
public static ListNode partition(ListNode head, int x){
ListNode smallerhead=new ListNode(0);
ListNode biggerhead=new ListNode(0);
ListNode smaller=smallerhead;
ListNode bigger=biggerhead;
while(head!=null){
if(head.val<x){
smaller.next=head;
   smaller=smaller.next;
}else{
bigger.next=head;
bigger=bigger.next;
}
head=head.next;
}
//no need for extra check because of fake heads
smaller.next=biggerhead.next;
bigger.next=null;
return smallerhead.next;
}
//reverse node in k groups
public static ListNode reverseKGroup(ListNode head,int k){
ListNode curr=head;
int count=0;
//find the k+1 node
while(curr!=null&& count!=k){
curr=curr.next;
count++;
}
if(count==k){
curr=reverseKGroup(curr,k);
//head: head-pointer to direct part
//curr:head-pointer to reversed part
while(count-->0){
ListNode tmp=head.next;
head.next=curr;
curr=head;
head=tmp;
}
head=curr;
}
return head;
}

public static ListNode reverseKGroup1(ListNode head, int k){
ListNode begin;
if(head==null||head.next==null||k==1){
return head;
}
ListNode dummyhead=new ListNode(-1);
dummyhead.next=head;
begin=dummyhead;
int i=0;
while(head!=null){
i++;
if(i%k==0){
begin=reversefromstarttoend(begin,head.next);
head=head.next;
}else{
head=head.next;
}
}
return dummyhead.next;
}
public static ListNode reversefromstarttoend(ListNode begin, ListNode end){
ListNode curr=begin.next;
ListNode next,first;
ListNode prev=begin;
first=curr;
while(curr!=end){
next=curr.next;
curr.next=prev;
prev=curr;
curr=next;
}
begin.next=prev;
first.next=curr;
return first;
}
}


class Heap{
public List<ListNode> heap;
private int getLimit(){
return heap.size()-1;
}
Heap(List<ListNode> lists){
heap=new ArrayList<ListNode>();
heap.add(new ListNode(0));
int i=0;
while(i<lists.size()){
if(lists.get(i)!=null){
heap.add(lists.get(i));
}
++i;
}
}
public void heapAdjust(int n,int m){
ListNode value=new ListNode(0);
copy(heap.get(n),value);
for(int i=2*n;i<=m;i*=2){
if(i<m && heap.get(i).val>heap.get(i+1).val){
i++;
}
if(heap.get(i).val>value.val){
break;
}
copy(value,heap.get(n));
n=i;
}
copy(value,heap.get(n));
}

private void copy(ListNode s,ListNode t){
if(s==null){
s=new ListNode(t.val);
}
t.next=s.next;
t.val=s.val;
}
public void creatMinHeap(){
for(int i=getLimit()/2;i>0;--i){
heapAdjust(i,getLimit());
}
}
public ListNode getHeap(){
if(heap.size()==1){
return null;
}
if(heap.get(1)==null){
return null;
}
ListNode result =new ListNode(0);
copy(heap.get(1),result);
if(heap.get(1).next!=null){
copy(heap.get(1).next,heap.get(1));
}else{
copy(heap.get(heap.size()-1),heap.get(1));
heap.remove(heap.size()-1);
}
if(heap.size()!=1){
heapAdjust(1,getLimit());
}
return result;
}
public int getlen(){
return heap.size()-1;
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值