Java链表应用

Java链表应用链表类publicclassListNode{intval;ListNodenext=null;ListNode(intval){this.val=val;}}1、返回倒数第k个结点前后指针法需要考虑k大于链表长度的情况publicclassSolution{publicL…

大家好,又见面了,我是你们的朋友全栈君。

链表类

public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

1、返回倒数第k个结点

前后指针法

需要考虑k大于链表长度的情况

public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(k <= 0) {
        	return null;
        }
        ListNode pre = head;
        ListNode cur = head;
        for(int i = 0; i <k -1; i++) {
        	if(cur == null) {
        		return null;//处理k大于链表长度的情况
        	}
        	cur = cur.next;
        }
        if(cur == null) {
        	return null;
        }
        while(cur.next != null) {
        	pre = pre.next;//前后指针
        	cur = cur.next;
        }
        return pre;
    }
}

2、返回两个无环链表的交点

public class Solution2 {
	
	public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
		 int length1 = getListLength(pHead1);
		 int length2 = getListLength(pHead2);
		 int lengthD = length1 - length2;
		 ListNode pLong = pHead1;
		 ListNode pShort = pHead2;
		 if(length1 < length2) {
			 pLong = pHead2;
			 pShort = pHead1;
			 lengthD = -lengthD;
		 }
		 //长链表先走lengthD的长度
		 for(int i = 0; i < lengthD; i++) {
			 pLong = pLong.next;
		 }
		 //两个链表同步走,值相等时停止返回
		 while(pLong != null && pShort != null && pLong != pShort) {
			 pLong = pLong.next;
			 pShort = pShort.next;
		 }
		 return pShort;
    }

	private int getListLength(ListNode pHead1) {
		int length = 0;
		ListNode node = pHead1;
		while(node != null) {
			length++;
			node = node.next;
		}
		return length;
	}
}

3、删除排序链表的重复结点,重复结点不保留 

public class Solution3 {
	public ListNode deleteDuplication(ListNode pHead){
		if(pHead == null || pHead.next == null) {
			return pHead;
		}
		
		if(pHead.val == pHead.next.val) {
			ListNode aft = pHead.next;
			while(aft != null && aft.val == pHead.val) {//跳过所有相同的值,找到第一个不同的值
				aft = aft.next;
			}
			return deleteDuplication(aft);//从第一个不同的值继续递归
		}
		else {
			//当前没有重复元素,就从下一个节点开始
			pHead.next = deleteDuplication(pHead.next);
			return pHead;
		}
    }
}

4、输入一个链表,按链表值从尾到头的顺序返回一个ArrayList

将该链表的值保存在栈中

新建链表,添加栈pop的值

public class Solution4 {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        Stack<Integer> stack = new Stack<>();
        while(listNode != null){
            stack.push(listNode.val);
            listNode = listNode.next;
        }
        ArrayList<Integer> arrayList = new ArrayList<>();
        while(!stack.isEmpty()){
            arrayList.add(stack.pop());
        }
        return arrayList;
    }
}

5、右旋单链表,使每个结点向右移动n个位置,n为非负数

public class Solution5 {
	public ListNode rotateRight(ListNode head, int n) {
	    if(head == null || head.next == null || n == 0){
	        return head;
	    }
	 
	    int len = getLength(head);
	    if(n % len == 0) {
	    	return head;
	    }else {
	    	n %= len;
	    }
	    
	    ListNode mid = head;
	    ListNode pre = head;
	    for(int i = 0; i < len - n; i++){
	        pre = mid;
	        mid = mid.next;
	    }
	    pre.next = null;
	    ListNode newHead = mid;
	    while(mid.next != null){
	        mid = mid.next;
	    }
	    mid.next = head;
	    return newHead;
	}
	private int getLength(ListNode head){
	    ListNode node = head;
	    int len = 0;
	    while(node != null){
	        len++;
	        node = node.next;
	    }
	    return len;
	}
}

6、删除单链表中从后往前数的第n个结点

public class Solution6 {
	public ListNode removeNthFromEnd(ListNode head, int n) {
	    if(head == null){
	        return null;
	    }
	    
	    if(n <= 0){
	        return head;
	    }
	    
	    //前后指针
	    ListNode pre = head;
	    ListNode cur = head;
	    int i = 0;
	    for(; i < n && cur != null; i++){
	        cur = cur.next;
	    }
	    if(i < n) {//处理n大于链表长度的情况
	    	return head;
	    }
	    if(cur == null) {//头删
	    	head = head.next;
	    	return head;
	    }
	    
	    //cur与pre相差n-1个位置
	    //cur = null, pre在n+1处
        while(cur.next != null){
            pre = pre.next;
            cur = cur.next;
        }
        //删除pre
        pre.next = pre.next.next;
        
	    return head;
	}
}

7、反转链表

public class Solution7 {
    public ListNode ReverseList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        
        //三个指针遍历
        ListNode pre = null;
        ListNode node = head;
        ListNode aft = head.next;
        while(node != null){
            node.next = pre;
            pre = node;
            node = aft;
            if(aft != null){
                aft = aft.next;
            }
            else{
                aft = null;
            }
        }
        return pre;
    }
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/142640.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 关于将dede织梦data目录迁移出web目录

    关于将dede织梦data目录迁移出web目录

    2021年9月19日
    49
  • QueueUserWorkItem_thread.join()

    QueueUserWorkItem_thread.join()代码:ThreadPool.SetMaxThreads(100,100);ThreadPool.QueueUserWorkItem((obj)=>{MessageBox.Show(“执行线程中的代码”);});Thread.Sleep(1000);intn=8;ThreadPool.QueueUserWorkItem((obj…

    2022年9月24日
    0
  • matlab循环读取txt文件「建议收藏」

    matlab循环读取txt文件「建议收藏」一般情况下,假如我要读取一个名为a.txt的文件,只需要利用下面的语句:a=load(‘a.txt’);现在假如我需要循环读取saif_1.txt,saif_2.txt,,,一直到saif_10.txt,他们都是10*1的矩阵,对他们进行转置操作后,再合并到一个文件中,可以利用下面的语句:forN=1:10a=load([‘saif_’,num2str(N),’.txt’]);……

    2022年10月7日
    0
  • MOS管相关知识

    MOS管相关知识mos管相关知识

    2022年6月21日
    64
  • pycharm选择运行环境_安卓漂亮的界面

    pycharm选择运行环境_安卓漂亮的界面手把手教你配置最漂亮的PyCharm界面,Python程序员必备!简介:高逼格超美的IDE界面,是每个程序员的梦想!随着人工智能/机器学习的兴起,Python作为一门“漂亮的语言”,再次获得广大程序员的关注。而JetBrains出品的PyCharm无疑是最好用的PythonIDE之一。俗话说“工欲善其事,必先利其器”,把自己的IDE配置得既有逼格又好看,这是每个Python程序员必备的技能。推荐给大家一个学习交流的地方:719+139+688,本文就手把手的教你,如何把自己的PyCharm配置的

    2022年8月28日
    18
  • 芯片的架构_意法半导体

    芯片的架构_意法半导体在了解这些架构之前,我们应该先了解一下复杂指令集(CISC)和精简指令集(RISC)。怎么说这两个的区别呢?CISC的设计思路更加注重性能的发展,是一种高性能高功耗的芯片,在高密度的计算上更具有优势;RISC的设计思路更注重低功耗小尺寸,多用于移动端设备,在重复性任务上占优。举一个简单的例子来说明这个情况,我们在B站上常说的一键三连,CISC会把“点赞”“投币”“收藏”整理成一条指令在缓存中,再由处理器处理;但是对于RISC来说就是三条指令了先“点赞”再“投币”最后“收藏”,这样做的缺点就是很依赖内存带宽了

    2022年9月7日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号