首页 > 编程语言 >【算法-简单01】合并2个有序数列

【算法-简单01】合并2个有序数列

时间:2022-10-06 16:35:15浏览次数:48  
标签:01 ListNode 数列 val list1 next 算法 list2 迭代

合并2个有序数列

  • 结果:

    • 时间复杂度:O(N)
    • 空间复杂度:O(N)
  • 比较抽象的点

    • 结论:Node对象有3个属性:Node本身、val,以及Node.next
      • Node本身判空,结合while来进行遍历查询
      • val大小判断,来进行ab -> ba,保证指针遍历的方向是递增的
      • Node.next判空,用来判断传递指针的边界
    • 问题:在哪一步运用迭代?迭代过程主要做什么事情?迭代结束又要做什么事情?在哪里返回List?怎么保证从小到大的顺序是正确的?又如何判断迭代何时结束?
      • 先从简单的例子开始观察
      • 其中的最小组合ab
        • ab要判断大小
        • ab要判断是否含有next
        • 假定a<=b,否则二者换顺序
        • 判断到最后,发现就是间隔最小的2个!
        • 链接即可
        • 自动迭代
    • 草图
      image
    • 迭代的逻辑:a.next=M(a,b):
      • 默认a<=b,否则就换顺序,这里会增加空间复杂度吗?
      • 如果a<=b,就比较M(a.next,b)。因为上一条的逻辑,M一定可以按正确的顺序迭代到尽头
      • 到了尽头、即不存在next了,通过null = a.next来判断
      • a.next=b完成最后一个元素的链接
    • 延伸:如果2个list都是无序的呢?
      • 方案一:先对每个list自己排序,再调用上面的合并方法
      • 方案二:再想……
  • 实现方法:将添加、遍历、合并分成三个方法, 以免过于纠缠

    • 先构建基本的ListNode对象
    //构建测试方法
    
    //构建基本的Node对象
    package collections;
    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; }
    
    }
    
    • 再构建测试类ListTest对象
    package collections;
    import org.junit.Test;
    public class ListTest {
        @Test
        public void testList(){
            int[] a = {9,19,20,25,29};
            int[] b = {11,22,28,100};
            ListNode list1 = addNode(a);
            ListNode list2 = addNode(b);
            try{
            ListNode list = mergeTwoLists(list1,list2);
            printNode(list);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    • 构建方法:实现Array -> ListNode
    public ListNode addNode(int[] ints){
        ListNode pointer = new ListNode();
        ListNode list1 = pointer;
        //构造ListNode
        for(int i = 0;i<ints.length-1;i++){
            pointer.val = ints[i];
            pointer.next = new ListNode(ints[i+1]);
            pointer = pointer.next;
        }
        //调用方法,遍历ListNode
        System.out.println("添加的List长度是:"+ints.length);
        printNode(list1);
        return list1;
    }
    
    • 构建方法:遍历ListNode
    public void printNode(ListNode node){
        ListNode testNode = node;
        System.out.println("ListNode遍历如下:");
        while(null!=testNode){
            System.out.println(testNode.val);
            testNode = testNode.next;
        }
    }
    
    • 构建方法:合并2个ListNode
    public ListNode mergeTwoLists(ListNode list1,ListNode list2){
        //先判断是否有next,有就迭代指针,没有就追加
        //value仅用来判断大小,交换位置,确保左小右大
        if(list1.val>list2.val){
            ListNode listNode = new ListNode();
            listNode = list1;
            list1 = list2;
            list2 = listNode;
        }
        if(null!=list1.next){
            //非常关键的一步迭代,迭代的意义仅仅是按正确的顺序传递指针
            list1.next = mergeTwoLists(list1.next,list2);
            System.out.println("指针传递到:"+list1.next.val);
        }else{
            //迭代的尽头就找到了最小间隔a和b,必要的操作是给二者添加链接
            //(删除线,中间的调序操作已经随着每次迭代进行判定和操作了,否则无法找到正确的顺序方向)找到尽头之后,会按指针传递的顺序反向、逐个操作添加链接,完成合并
            //找到尽头后,最后2个元素完成链接,迭代结束,返回list
            list1.next = list2;
            System.out.println("追加了"+list2.val);
        }
        return list1;
    }   
    

标签:01,ListNode,数列,val,list1,next,算法,list2,迭代
From: https://www.cnblogs.com/zhuyucode/p/16757854.html

相关文章

  • 算法上亟待解决的问题
    这就是某市第一高中与某市“第二”高中的差距。被文化课扫地出门后去好学校见了见世面,我什么都不会。而且问题甚至不在代码实现这一环,而是我根本不知道这一堆知识点。列......
  • P4384 [八省联考 2018] 制胡窜
    P4384[八省联考2018]制胡窜考虑先将问题转化为切断两个位置使得没有任何一段中包含\(t\)。则最终的答案为\(\dbinom{n}{2}-\text{ans}\)。计\(t\)按左端点排序后......
  • day01
    markdown学习标题一级标题(#空格标题名字)二级标题(##空格标题名字)三级以下类推逐加#回车即可字体斜体:字体俩边加1星号(eg:hello)粗体:字体俩边加2星号(eg:hello)即粗又斜:......
  • P2305 [NOI2014] 购票
    P2305[NOI2014]购票设\(f_{x}\)表示从\(x\)点跳到\(1\)的最少费用。考虑\(x\)的一个祖先\(u\),有\[f_x=f_{u}+\text{dis}_{u,x}\timesp_x+q_x\]其中需要满足......
  • AT2371 [AGC013E] Placing Squares
    AT2371[AGC013E]PlacingSquares设\(f_i\)表示考虑到第\(i\)个点的贡献之和且不考虑坏点。不难发现转移方程为\(f_n=\sum_{i=0}^nf_i\times(n-i)^2\)则当第\(n......
  • 算法竞赛备赛之浅谈递归
    递归递归需要有基例、递归前进段和递归返回段(return语句),是一种程序设计技巧,可以使程序编写简单,但实际上要付出低效率的代价计算时间复杂度常用数据的记忆(程序设计基本功,......
  • 014——static应用知识:单例设计模式
    static应用知识:单例设计模式设计模式开发中经常遇到一些问题,一个问题通常有n种解法的,但其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式。......
  • Codeforces Round #801 (Div. 2) C(规律证明)
    CodeforcesRound#801(Div.2)C(规律证明)题目链接:传送门QAQ题意:给定一个\(n*m\)的矩阵,矩阵的每个单元的值为1或-1,问从\((1,1)\)开始出发,每次只可以向下和向右走,......
  • 程序员必备的基本算法:递归详解
    前言递归是一种非常重要的算法思想,无论你是前端开发,还是后端开发,都需要掌握它。在日常工作中,统计文件夹大小,解析xml文件等等,都需要用到递归算法。它太基础太重要了,这也是为......
  • 斐波那契数列
    什么是斐波那契数列斐波那契数列(Fibonaccisequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2......