【学习笔记】leetcode每日五题(9.26)

每日五题(9.26)

1.删除链表的倒数第 n 个结点

链接:https://leetcode.cn/problems/SLwz0R/

给定一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

img

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

思路:遍历两边链表?第一次知道总共多长,第二次找到待删除点,前面的指向后面即可

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        //创建一个数值为0,下一个节点为头节点的新节点
        ListNode dummy = new ListNode(0, head);
        //获取头节点之和的长度
        int length = getLength(head);
        ListNode cur = dummy;
        //cur一直遍历,直至找到目标待删点前一个点
        for (int i = 1; i < length - n + 1; ++i) {
            cur = cur.next;
        }
        //cur的下一个变成下下一个,即上图3直接指向5,跳过4
        cur.next = cur.next.next;
        //头节点
        ListNode ans = dummy.next;
        return ans;
    }

    public int getLength(ListNode head) {
        int length = 0;
        while (head != null) {
            ++length;
            head = head.next;
        }
        return length;
    }
}


作者:LeetCode-Solution
链接:https://leetcode.cn/problems/SLwz0R/solution/shan-chu-lian-biao-de-dao-shu-di-n-ge-ji-ydte/
来源:力扣(LeetCode)

2.链表中环的入口节点

链接:https://leetcode.cn/problems/c32eOV/

给定一个链表,返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

img

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

img

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

思路:

两种方法:

哈希表和快慢指针

哈希表:我们使用不可重复的哈希表,从头节点遍历链表,直到某处添加失败,此处便是环的入口

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode pos = head;
        Set<ListNode> visited = new HashSet<ListNode>();
        while (pos != null) {
            if (visited.contains(pos)) {
                return pos;
            } else {
                visited.add(pos);
            }
            pos = pos.next;
        }
        return null;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/c32eOV/solution/lian-biao-zhong-huan-de-ru-kou-jie-dian-vvofe/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

快慢指针:我们使用两个指针,fast和slow,fast每次走两个节点,slow每次一个节点,当快慢指针相遇,并满足了一定的条件时,该节点就是目标入口节点此方法请查看链接https://leetcode.cn/problems/c32eOV/solution/lian-biao-zhong-huan-de-ru-kou-jie-dian-vvofe/

3.两个链表的第一个重合节点

链接:https://leetcode.cn/problems/3u1WK4/

给定两个单链表的头节点 headA 和 headB ,请找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

图示两个链表在节点 c1 开始相交:

img

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构

示例:

img

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

思路解析:

哈希表,使用哈希表先遍历A链直至最后,再使用此哈希表遍历存储B链,如果有重复,即哈希表存储失败,那么此处节点即为我们所求

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> visited = new HashSet<ListNode>();
        ListNode temp = headA;
        while (temp != null) {
            visited.add(temp);
            temp = temp.next;
        }
        temp = headB;
        while (temp != null) {
            if (visited.contains(temp)) {
                return temp;
            }
            temp = temp.next;
        }
        return null;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/3u1WK4/solution/liang-ge-lian-biao-de-di-yi-ge-zhong-he-0msfg/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4.反转链表

链接:https://leetcode.cn/problems/UHnkqh/

给定单链表的头节点 head ,请反转链表,并返回反转后的链表的头节点。

img

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

思路解析:

栈:使用栈,后进先出,所以先弹出来的,将会是末尾的,再将末尾的指向下一个弹出来的即可

迭代:我们遍历链表时,创建一个prev用以存储当前节点的前节点,当指向修改完毕之后,将当前节点和前节点都后移一个位置

class Solution {
    public ListNode reverseList(ListNode head) {
        //存储前一个节点
        ListNode prev = null;
        //存储当前节点,初始为头节点
        ListNode curr = head;
        while (curr != null) {
            //创建next为当前节点的下一个节点
            ListNode next = curr.next;
            //当前节点的下一个节点改为前节点
            curr.next = prev;
            //前节点更新为当前节点
            prev = curr;
            //当前节点更新为下一个节点
            curr = next;
        }
        return prev;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/UHnkqh/solution/fan-zhuan-lian-biao-by-leetcode-solution-34oi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

5.链表中的两数相加

链接:https://leetcode.cn/problems/lMSNwu/

给定两个 非空链表 l1和 l2 来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。

可以假设除了数字 0 之外,这两个数字都不会以零开头。

img

输入:l1 = [7,2,4,3], l2 = [5,6,4]
输出:[7,8,0,7]

思路解析:

我们要从链表的末尾进行处理,所以我们可以使用栈来处理。将两个链表所有的元素存入栈中,再从栈中一个一个弹出使用

因为链表的长度可以很长,长到超过java的数据限制,所以我们需要使用传统一点的方式进行操作

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //创建两个栈
        Deque<Integer> stack1 = new ArrayDeque<Integer>();
        Deque<Integer> stack2 = new ArrayDeque<Integer>();
        //存入数据进链表中
        while (l1 != null) {
            stack1.push(l1.val);
            l1 = l1.next;
        }
        while (l2 != null) {
            stack2.push(l2.val);
            l2 = l2.next;
        }
        int carry = 0;
        ListNode ans = null;
        while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
            //取出两个链表的末尾数,如果没有,则为0
            int a = stack1.isEmpty() ? 0 : stack1.pop();
            int b = stack2.isEmpty() ? 0 : stack2.pop();
            //二者相加,carry为进位
            int cur = a + b + carry;
            carry = cur / 10;
            //cur模掉10,剩个位数
            cur %= 10;
            //存入cur进入节点中
            ListNode curnode = new ListNode(cur);
            //连接节点
            curnode.next = ans;
            ans = curnode;
        }
        return ans;
    }
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/lMSNwu/solution/lian-biao-zhong-de-liang-shu-xiang-jia-b-cpk2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值