NowCoderTOP1-6——持续更新ing

Posted 王嘻嘻-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NowCoderTOP1-6——持续更新ing相关的知识,希望对你有一定的参考价值。

TOP1 反转链表

package NowCoder;

/**
 * 反转链表
 * 给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。
 **/
public class top1 
    public ListNode ReverseList(ListNode head) 
        // 新链表头节点指向空
        ListNode newHead = null;
        while (head.next != null) 
            // 1. 先保存下一个节点
            ListNode next = head.next;
            // 2. 原链表的第一个节点指向 newHead
            head.next = newHead;
            // 3. newHead指向head,head指向下一个节点
            newHead = head;
            head = next;
        
        return newHead;
    

TOP2 链表内指定区间进行反转

package NowCoder;

/**
 * 将链表指定位置进行反转
 * 将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。
 * 例如:
 * 给出的链表为 1\\to 2 \\to 3 \\to 4 \\to 5 \\to NULL 1 → 2 → 3 → 4 → 5 → NULL, m=2,n=4m=2,n=4,
 * 返回 1\\to 4\\to 3\\to 2\\to 5\\to NULL 1 → 4 → 3 → 2 → 5 → NULL.
 **/
public class top2 
    /**
     * @param head ListNode类
     * @param m int整型
     * @param n int整型
     * @return ListNode类
     */
    public ListNode reverseBetween (ListNode head, int m, int n) 
        // 定义一个虚拟头节点
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        // 前序节点
        ListNode pre = dummyHead;
        // 当前头节点
        ListNode cur = head;
        // 找到 m 所在的节点位置
        for (int i = 1; i < m; i++) 
            pre = cur;
            cur = cur.next;
        
        // 此时已经找到了 m 节点所在的位置,遍历节点 m ~ n,反转链表
        for(int i = m; i < n ; i++) 
            ListNode temp = cur.next;
            cur.next = temp.next;
            temp.next = pre.next;
            pre.next = temp;
        
        return dummyHead.next;
    

TOP3 链表中的节点每k个一组翻转

package NowCoder;

/**
 * 链表中的节点每k个一组翻转
 * 将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
 * 如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
 * 你不能更改节点中的值,只能更改节点本身。
 **/
public class top3 
    /**
     * @param head ListNode类
     * @param k int整型
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) 
        // 运用递归的思想
        ListNode tail = head;
        for (int i = 0; i < k; i++) 
            // 当尾节点遍历至空,直接返回其头节点
            if (tail == null) return head;
            tail = tail.next;
        
        // 此时已经找到要翻转的区间
        // 定义前驱节点和当前节点
        ListNode pre = null;
        ListNode cur = head;
        // 此时tail指向下一个区间的首节点
        while (cur != tail) 
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        
        // 到这里一段区间的翻转已完成,递归拼接其他的区间
        // 递归下一区间,当前区间尾部指向下一个要翻转的链表
        head.next = reverseKGroup(tail, k);
        // 最后的 pre 指头节点
        return pre;
    

TOP4 合并两个排序的链表

package NowCoder;

/**
 * 合并两个排序的链表
 * 输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。
 **/
public class top4 
    public ListNode Merge(ListNode list1,ListNode list2) 
        // 先判断 list1 和 list2 为空时
        if (list1 == null || list2 == null) 
            return list1 != null ? list1 : list2;
        
        // 此时两个链表都不为空,递归比较两个链表中各元素的值
        if (list1.val <= list2.val) 
            list1.next = Merge(list1.next, list2);
            return list1;
        else 
            list2.next = Merge(list1, list2.next);
            return list2;
        
    

TOP5 合并k个已排序的链表

package NowCoder;

import java.util.ArrayList;

/**
 * 合并k个已排序的链表
 * 合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
 * 递归
 * 终止条件: 划分的时候直到左右区间相等或左边大于右边。
 * 返回值: 每级返回已经合并好的子问题链表。
 * 本级任务: 对半划分,将划分后的子问题合并成新的链表。
 **/
public class top5  
    public ListNode mergeKLists(ArrayList<ListNode> lists) 
        return divideMerge(lists, 0 , lists.size() - 1);
    

    // 划分合并区间函数
    public ListNode divideMerge(ArrayList<ListNode> lists, int left , int right) 
        if (left > right) 
            return null;
        else if (left == right)
            // 此时在区间里边
            return lists.get(left);
        
        int mid = (left + right) / 2;
        return Merge(divideMerge(lists,left,mid),divideMerge(lists,mid + 1,right));
    

    // 合并两个链表
    public  ListNode Merge(ListNode list1 , ListNode list2) 
        if (list1 == null) return list2;
        if (list2 == null) return list1;
        // 此时两个链表都不为空
        // 定义一个虚拟头节点
        ListNode dummyHead = new ListNode(0);
        ListNode cur = dummyHead;
        while (list1 != null || list2 != null) 
            // 此时比较两个链表中各个元素的值
            if (list1.val <= list2.val) 
                cur.next = list1;
                list1 = list1.next;
            else 
                cur.next = list2;
                list2 = list2.next;
            
            cur = cur.next;
        
        // 此时两个链表有一个为空
        if (list1 == null) cur.next = list2;
        else cur.next = list1;
        // 返回虚拟头节点的下一个节点
        return  dummyHead.next;
    

TOP6 判断链表中是否有环

package NowCoder;

/**
 *  判断链表中是否有环
 * step 1:设置快慢两个指针,初始都指向链表头。
 * step 2:遍历链表,快指针每次走两步,慢指针每次走一步。
 * step 3:如果快指针到了链表末尾,说明没有环,因为它每次走两步,所以要验证连续两步是否为NULL。
 * step 4:如果链表有环,那快慢双指针会在环内循环,因为快指针每次走两步,因此快指针会在环内追到慢指针,二者相遇就代表有环。
 **/
public class top6 
    public boolean hasCycle(ListNode head) 
        // 边界条件
        if (head == null) return false;
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) 
            fast = fast.next.next;
            slow = slow.next;

            if (fast == slow) 
                return true;
            
        
        return false;
    

        while (fast != null && fast.next != null) 
            fast = fast.next.next;
            slow = slow.next;

            if (fast == slow) 
                return true;
            
        
        return false;
    

以上是关于NowCoderTOP1-6——持续更新ing的主要内容,如果未能解决你的问题,请参考以下文章

JMeter参考文章列表(持续更新ing)

FireFox所支持的全部标签(持续更新ing)

NowCoderTOP12-16——持续更新ing

NowCoderTOP12-16——持续更新ing

2023届秋招提前批信息汇总(持续更新ing)

UG编程从入门到精通视频持续更新ing