Java链表面试题(2)

import java.util.HashMap;
import java.util.Hashtable;
Class Node{
     int value;
     Node next;
}
Class CNode extends Node{
      Node random;
      CNode next;
      public CNode(int value){
      this.value=value;
      this.next=null;
      this.random=null;
      }
}

public class Solution {
  /**
     * 对链表进行排序
     * @param head 需要排序的链表
     * @return  排序后的链表
     */
    public static Node linkSort(Node head){
        if(head==null){
            return head;
        }
        Node tmp=head;
        while(tmp!=null){
            Node q=tmp.next;
            while(q!=null){
                if(tmp.value>q.value){
                    int t=tmp.value;
                    tmp.value=q.value;
                    q.value=t;
                }
                q=q.next;
            }

           tmp=tmp.next;
        }
        return head;
    }

    /**
     * 去掉链表中重复的元素,在这里借助了HashTable用来排除已经存在的元素
     * @param head 传入的有重复元素的链表
     * @return  去掉重复元素的新链表
     */
    public static Node distinctLink(Node head){
        if(head==null){
            return head;
        }
        Node newNode=new Node();
        Node p=newNode;
        Node cur=head;
        Hashtable<Integer,Integer> tb=new Hashtable<>();
        while(cur!=null){
            if(tb.containsKey(cur.value)){
                cur=cur.next;
            }else{
                tb.put(cur.value,1);
                p.next=cur;
                p=cur;
                cur=cur.next;
            }

        }
        return newNode.next;
    }

    /**
     * 删除倒数第K个节点,这里使用一个快指针和一个慢指针
     * @param head  传入的链表
     * @param k 需要删除的倒数第K个节点
     * @return 删除元素后的链表
     */
    public static Node findRemoveNode(Node head,int k){
        if(head==null){
            return head;
        }
        Node pre=head;
        Node last=null;
        for(int i=0;i<k-1;i++){//i<k-1,比如K=2,这里pre已经指向了head节点,所以它只需要向后移动一位即可
            if(pre!=null){
                pre=pre.next;
            }else{
                return head;
            }
        }
        if(pre!=null){
            while(pre.next!=null){//在这里如果条件写成pre!=null,就会导致链表最后一个元素找不见了
                pre=pre.next;
                if(last==null){
                    last=head;
                }else{
                    last=last.next;
                }
            }
            last.next=pre;
        }
        return head;
    }
   /**
     * 查找正数第K个元素
     * @param k  需要查找的第几个元素
     * @return  返回查找后的节点
     */
    public static Node findNode(Node head,int k){
        Node cur=head;
        for(int i=0;i<k-1;i++){
            if(cur.next!=null){
                cur=cur.next;
            }else{
                return head;
            }
        }
        Node ret=new Node();
        ret.value=cur.value;

        return ret;
    }
 /**
     * 寻找已知头结点链表的中间节点,这里是有一个快指针一个慢指针,快指针走两步,慢指针走一步
     * @param head 传入链表头结点
     * @return 返回找到的节点
     */
    public static Node findMiddleNode(Node head){
        if(head==null){
            return head;
        }
        Node pre=head;
        Node last=head;
        while(pre.next!=null && pre.next.next!=null){
            pre=pre.next.next;
            last=last.next;
        }
        Node ret=new Node();
        ret.value=last.value;
        return ret;
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值