Leetcode-JAVA版本链表专题学习

002两数相加

代码(对应结点相加)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1,ListNode l2) {
		/*
		 题目信息:
		 两个非空的链表
		 逆序存储
		 除了数字0不会以0开头
		 */
		/*
		 * 依次相加
		 * 注意考虑进位
		 */
//		创建头结点
		ListNode head=new ListNode();
//		指向head
		ListNode node=head;
//		依次将每个结点相加,记得考虑进位
//		初始化进位为0
		int so=0;
//		遍历两个链表叠加
//		直到两个链表均遍历完
		ListNode p=l1;
		ListNode q=l2;
		while(p!=null||q!=null) {
//			初始化进位、两个对应结点的和为进位大小
			int sum=so;
			if(p!=null) {
				sum+=p.val;
			}
			if(q!=null) {
				sum+=q.val;
			}
//			创建node的下一个结点,大小为sum%10;
			node.next=new ListNode(sum%10);
//			更新进位
			so=sum/10;
			/*
			 * 记得要考虑p、q结点是否为null
			 */
			if(p!=null) {
				p=p.next;
			}
			if(q!=null) {
				q=q.next;
			}
			node=node.next;
		}
//		叠加之后要考虑是否仍存在进位,是否需要创建新结点
		if(so==1) {
			node.next=new ListNode(so);
		}
		return head.next;
	}
}

019删除链表的倒数第N个结点

代码一(倒数转正数)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 倒数转换为整数
        // 先计算链表长度
        ListNode p=head,q=head;
        // 记录链表长度
        int size=0;
        // 求链表长度
        while(p!=null){
            size++;
            p=p.next;
        }
        // 除去第一个结点的时候
        /*
        易错点:
        下面的
        int t=size-n
        t代表的是要删除的结点前面有几个结点,
        而该链表head没有头结点
        故前面有0个结点
        要单独拿出来讨论
        */
        if(size==n){
            return head.next;
        }
        // 记录删除结点的前一个结点的正数位置
        int t=size-n;
        int i=1;
        // 找要删除的结点的前一个结点
        while(i!=t){
            q=q.next;
            i++;
        }
        // 删除结点
        q.next=q.next.next;
        return head;
    }
}

代码二(学习双指针)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 创建头结点
        // 删除结点时要知道其前一个结点
        ListNode node=new ListNode();
        node.next=head;
        ListNode node1=node,node2=node;
        // 第一个先遍历n+1个结点
        int i=0;
        while(i<=n){
            i++;
            node1=node1.next;
        }
        // node1与node2一直相差n+1,当node1遍历完,node2即为要删除的结点的前一个结点
        // 故node1先遍历了n+1个结点而非n个结点
        while(node1!=null){
            node1=node1.next;
            node2=node2.next;
        }
        node2.next=node2.next.next;
        return node.next;
    }
}

代码三(利用数组)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        List<ListNode>list=new ArrayList<>();
        ListNode node=head;
        // 记录链表长度
        int size=0;
        // 求链表长度,并将结点存入数组
        while(node!=null){
            size++;
            list.add(node);
            node=node.next;
        }
        // 删除第一个结点
        if(n==size){
            return head.next;
        }
        // 删除其他结点
        else{
            ListNode re=list.get(size-n-1);
            re.next=re.next.next;
            return head;
        }
    }
}

021合并两个有序链表

代码一(遍历链表)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        // 链表list1为空
        if(list1==null&&list2!=null){
            return list2;
        }
        // 链表list2为空
        else if(list1!=null&&list2==null){
            return list1;
        }
        // 两个链表都为空
        else if(list1==null&&list2==null){
            return null;
        }
        // 两个链表都不为空
        else{
            // 创建头结点
            ListNode head=new ListNode();
            ListNode node=head;
            // 遍历链表list1,list2
            while(list1!=null&&list2!=null){
                // 当前遍历list1的结点的val较小或者两者相等
                if(list1.val<=list2.val){
                    node.next=list1;
                    list1=list1.next;
                    node=node.next;
                }
                else{
                    node.next=list2;
                    list2=list2.next;
                    node=node.next;
                }
            }
            // 当list1未遍历完
            if(list1!=null){
                node.next=list1;
            }
            // 当list2未遍历完
            else if(list2!=null){
                node.next=list2;
            }
            return head.next;
        }

    }
}

代码二(学习递归,暂时不会)

023合并K个升序链表

代码一(利用数组)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        // 将结点的val值存入数组中
        List<Integer> list=new ArrayList<>();
        for(ListNode node:lists){
            while(node!=null){
                list.add(node.val);
                node=node.next;
            }
        }
        //数组排序
        Collections.sort(list);
        // 创建链表
        ListNode list1=new ListNode();
        ListNode node=list1;
        for(int val:list){
            node.next=new ListNode(val);
            node=node.next;
        }
        return list1.next;
    }
}

代码二(学习优先队列,暂时不会)

代码三(学习分治算法,暂时不会)

024两两交换链表中的节点

代码一

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        // 判断是否为空
        if(head==null){
            return null;
        }
        // 用于记录当前遍历的结点的位次,结点总数
        int size=0;
        ListNode p=head;
        // 记录相邻结点翻转后的链表
        ListNode list=new ListNode();
        ListNode node=list;
        while(p!=null){
            // 结点的个数++
            size++;
            // 目的:记录第偶数个结点
            ListNode q=p;
            p=p.next;
            // 表明是第偶数个
            if(size%2==0){
                node.next=q;
                node=node.next;
                node.next=head;
                /*
                head.next=null不可漏掉,不然会陷入循环
                比如1 2 3 4
                list为头结点->2->1->4->3此时按道理说遍历完结束了
                但实际为
                list为头结点->2->1->4->3->4->3->4->3。。。。4,3一直循环,这是 因为原链表3指向4,但是我们没有改变
                */
                head.next=null;
                node=node.next;
                head=p;
            }
            
        }
        // 判断是否结点数是否为奇数,若为奇数,则有一个不用翻转,未添加
        if(size%2!=0){
            node.next=head;
            head.next=null;
        }
        return list.next;
    }
}

代码二(学习递归,暂时不会)

代码三(学习迭代,暂时不会)

025K个一组链表翻转

代码一

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode head1=head;
        // 记录结点个数
        int size=0;
        // 求结点个数
        while(head1!=null){
            size++;
            head1=head1.next;
        }
        // 将结点val值存入数组
        int[] arr=new int [size];
        int i=0;
        while(head!=null){
            arr[i++]=head.val;
            head=head.next;
        }
        // 记录循环的周期数
        int circles=size/k;
        // 记录翻转的链表
        ListNode newHead=new ListNode();
        ListNode node=newHead;
        int p=1;
        int q=k;
        int size1=0;
        while(p<=circles){
            while(q>(p-1)*k){
                node.next=new ListNode(arr[q-1]);
                size1++;
                node=node.next;
                q--;
            }
            p++;
            q=p*k;
        }
        // 检查是否有周期以外未遍历的结点
        while(size1<arr.length){
            node.next=new ListNode(arr[size1]);
            node=node.next;
            size1++;
        }
        return newHead.next;
    }
}

代码二(学习递归,暂时不会)

代码三(学习迭代,暂时不会)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值