【英雄算法联盟】6月集训Day12.链表

一、今日练习题目:

328. 奇偶链表

给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。

725. 分隔链表

给你一个头结点为 head 的单链表和一个整数 k ,请你设计一个算法将链表分隔为 k 个连续的部分。每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。这 k 个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面的长度。返回一个由上述 k 部分组成的数组。

1290. 二进制链表转整数

给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。请你返回该链表所表示数字的 十进制值 。
**输入:**head = [1,0,1] **输出:**5 **解释:**二进制数 (101) 转化为十进制数 (5)

237. 删除链表中的节点

请编写一个函数,用于 删除单链表中某个特定节点 。在设计函数时需要注意,你无法访问链表的头节点 head ,只能直接访问 要被删除的节点 。题目数据保证需要删除的节点 不是末尾节点 。
**输入:**head = [4,5,1,9], node = 5 输出:[4,1,9] **解释:**指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9

剑指 Offer II 024. 反转链表

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

1019. 链表中的下一个更大节点

给定一个长度为 n 的链表 head。对于列表中的每个节点,查找下一个 更大节点 的值。也就是说,对于每个节点,找到它旁边的第一个节点的值,这个节点的值 严格大于 它的值。返回一个整数数组 answer ,其中 answer[i] 是第 i 个节点( 从1开始 )的下一个更大的节点的值。如果第 i 个节点没有下一个更大的节点,设置 answer[i] = 0 。
**输入:**head = [2,1,5]
输出:[5,5,0]

二、源码分析

题目1:328. 奇偶链表
/**
 * 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 oddEvenList(ListNode head) {
        if (head == null) return head;
        ListNode evenHead = head.next;
        ListNode odd = head, even = evenHead;
        while (even != null && even.next != null) {
            odd.next = even.next;
            odd = odd.next;
            even.next = odd.next;
            even = even.next;
        }
        odd.next = evenHead;
        return head;
    }
}

奇偶指针循环链表,奇数指针不断串连奇数节点,偶数指针不断串连偶数节点,最后奇数指针的结尾连接偶数节点的开始

题目2:725. 分隔链表
/**
 * 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[] splitListToParts(ListNode head, int k) {
        int cnt = 0;
        ListNode p = head;
        int len = 0;
        while (p!=null) {
            p = p.next;
            len++;
        }
        int per = len/k; // 计算每个数组的长度
        if (per == 0) per=1; // per可能为0,那样就每个长度设为1,后面的数组就是空
        int n = len - per*k; // 多出来的长度,要均分给前面
        p = head;
        ListNode[] ans = new ListNode[k];
        for (int i = 0; i<k&&p!=null; i++) {
            ans[i] = p;
            for(int j=0;j<per-1;j++){p=p.next;}//使用per-1是为了让p停留在每个部分的最后一个节点,方便后面的'断尾操作'
            if(n>0){n--;p=p.next;}//n>0的话就要均分,让p后移
            if(p!=null){ //断尾操作,然后后移
                ListNode temp=p.next;
                p.next=null;
                p=temp;
            }

        }
        return ans;
    }
}
题目3:1290. 二进制链表转整数
/**
 * 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; }
 * }
 */
/**
 * 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 int getDecimalValue(ListNode head) {
        ListNode curr = reverse(head);
        int result = 0;
        int pow = 0;
        while (curr != null) {
            if (curr.val != 0) {
                result += Math.pow(2, pow);
            }
            pow++;
            curr = curr.next;
        }

        return result;
    }

    private ListNode reverse(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        ListNode next = null;
        while (curr != null) {
            next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }

        return prev;
    }
}

先翻转链表,然后从头取低位开始转换十进制

题目4:237. 删除链表中的节点
public void deleteNode(ListNode node) {
    node.val=node.next.val;
    node.next=node.next.next;

}

node 的节点值修改为_node_.next 的节点的值,然后删除node.next即可

题目5:剑指 Offer II 024. 反转链表
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr!=null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
}
题目6:1019. 链表中的下一个更大节点
class Solution {
    public int[] nextLargerNodes(ListNode head) {
        // 把单链表转化成数组,方便通过索引访问
        ArrayList<Integer> nums = new ArrayList<>();
        for (ListNode p = head; p != null; p = p.next) {
            nums.add(p.val);
        }
        // 存放答案的数组
        int[] res = new int[nums.size()];
        Stack<Integer> stk = new Stack<>();
        // 单调栈模板,求下一个更大元素,从后往前遍历
        for (int i = nums.size() - 1; i >= 0; i--) {
            while (!stk.isEmpty() && stk.peek() <= nums.get(i)) {
                stk.pop();
            }
            // 本题要求没有下一个更大元素时返回 0
            res[i] = stk.isEmpty() ? 0 : stk.peek();
            stk.push(nums.get(i));
        }
        return res;
    }
}

这道题输入的是一条单链表,我们把它转化成数组,方便用索引访问即可直接使用单调栈的思路

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值