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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • visio安装教程2013_visio2018安装教程

    visio安装教程2013_visio2018安装教程下载地址:https://download.csdn.net/download/qq_33705529/11082285说到办公绘图软件,最强大的莫过于微软新推出的visio2013简体中文版,该软件可以帮助用户快速绘制工作中常用的业务流程图、组织结构图、项目管理图、网络…

    2022年9月28日
    2
  • PHP 常见设计模式——工厂模式

    PHP 常见设计模式——工厂模式今天这篇文章主要是描述一下PHP常见设计模式之工厂模式。工厂模式其实可以划分为:简单工厂模式、工厂方法模式、抽象工厂模式等。

    2022年7月25日
    8
  • win7下vs2008过期没有输入序列号的解决办法[通俗易懂]

    win7下vs2008过期没有输入序列号的解决办法[通俗易懂]vs2008在win7下过期后,无法找到升级的序列号输入框。使用网上修改Setup\setup.sdb不得法,输入序列号却没有输入的地方。经过查找发现在win7下序列号输入框已被隐藏,使用打补丁方式可现实输入框。

    2022年8月10日
    16
  • C++洗牌算法「建议收藏」

    1、使用标准库中的random_shuffle()函数实现很简单,代码如下:int main() {     vectorint> s_stl;     for (int i=0; i    random_shuffle(s_stl.begin(),s_stl.end());     cout “使用C++算法库:”;     for (vectorint>::iterator it=s_st

    2022年4月7日
    84
  • 计算机系统性能取决于,计算机的性能主要取决于什么,「建议收藏」

    计算机系统性能取决于,计算机的性能主要取决于什么,「建议收藏」计算机的性能主要取决于什么什么主要取决于电脑的性能,一台计算机的性能主要取决于字长、运算速度(每秒可以执行的指令数)、内存容量、外部内存容量、I/O速度、视频内存、硬盘速度、CPU主频(CPU内核的时钟频率)。微型计算机的功能或性能不是由某个指标决定的,而是由它的系统结构、指令系统、硬件组成、软件配置等因素决定的。但是对于大多数普通用户来说,电脑的性能一般可以从以下几个指标来评价。1.运行速度运算…

    2022年6月28日
    40
  • 如何在excel2019指定的单元格中插入图片

    如何在excel2019指定的单元格中插入图片最近,要完成一些论文的调研及整理工作,针对各个论文中提到的方法,系统模型等。原想在单元格中插入图片,发现单元格右键插入,压根就没插入图片这一项功能,如图所示故在菜单栏中,找到插入-》图片-》此设备,插入完成后,图片能在整个界面上移动。完全不是我想要的结果。问题解决办法如下:1、选中一个想要放入的单元格,尽量拉的大一点。2、把已插入的图拖到这个单元格内,大致调整一下大小,使其和单元格大小差不多。3、选中图片右键“大小和属性”。4、作如图设置,将属性选为“随单元格改变位置和大

    2025年6月29日
    2

发表回复

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

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