【算法】面试题 - 链表(附讲解视频)

news2025/1/17 23:21:00

链表相关面试题

  • 876. 链表的中间结点
  • 206. 反转链表
  • 86. 分隔链表
  • 160. 相交链表
  • 141. 环形链表
    • 问题:快慢指针为什么一定会相遇
  • 142. 环形链表 II
    • 问题:如何确认入口
  • 237. 删除链表中的节点
  • 19. 删除链表的倒数第 N 个结点
  • 21. 合并两个有序链表
  • 23. 合并K个升序链表(两种解法)
    • 扩展:[PriorityQueue](https://blog.csdn.net/yzx3105/article/details/128442507)
  • 2. 两数相加

876. 链表的中间结点

题目描述:
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例:1

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3(测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.

示例:2

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 34,我们返回第二个结点。

代码:

static ListNode middleNode(ListNode head) {
     ListNode fast = head;
     ListNode slow = head;
     
     while (fast.next != null && fast.next.next != null) {
         fast = fast.next.next;
         slow = slow.next;
     }
     //如果是奇数个节点,fast最后指向的是最后一个节点,如果是偶数个节点,fast最后指向的是倒数第二个节点
     //因此,如果fast.next==null,证明是奇数个节点,直接返回slow
     //如果fast.next.next==null,证明是偶数个节点,返回slow.next(返回第二个中间节点)
     if(fast.next == null){
         return slow;
     }else{
         return slow.next;
     }
 }

206. 反转链表

题目描述:
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例:1
在这里插入图片描述

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

示例:2
在这里插入图片描述

输入:head = [1,2]
输出:[2,1]

示例:3

输入:head = []
输出:[]

代码:

public ListNode reverseList(ListNode head) {
    ListNode dummy = new ListNode(0);
     while (head != null) {
         ListNode next = head.next;
         head.next = dummy.next;
         dummy.next = head;
         head = next;
     }
     return dummy.next;
 }

86. 分隔链表

题目描述:
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
示例:1
在这里插入图片描述

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

示例:2

输入:head = [2,1], x = 2
输出:[1,2]

代码:

/**
 * 利用两个链表,将小于num的节点放到minNodeHead链表,大于等于num的节点放到maxNodeHead链表,最后,将minNodeHead拼接maxNodeHead返回
 * @param head
 * @param num
 * @return
 */
static ListNode partition(ListNode head, int num) {
    ListNode minNodeHead = new ListNode(0);
    ListNode maxNodeHead = new ListNode(0);

    ListNode minPre = minNodeHead;
    ListNode maxPre = maxNodeHead;
    while (head != null) {
        if (head.val < num) {
            minPre.next = head;
            minPre = minPre.next;
        } else {
            maxPre.next = head;
            maxPre = maxPre.next;
        }
        head = head.next;
    }

    maxPre.next=null;
    minPre.next = maxNodeHead.next;
    return minNodeHead.next;
}

160. 相交链表

题目描述:
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
图示两个链表在节点 c1 开始相交:
在这里插入图片描述
示例:1
在这里插入图片描述

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A[4,1,8,4,5],链表 B[5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
— 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。

示例:2
在这里插入图片描述

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

示例:3
在这里插入图片描述

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A[2,6,4],链表 B[1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null

代码:

static ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode a = headA;
    ListNode b = headB;
    while (a != b) {
        a = a != null ? a.next : headB;
        b = b != null ? b.next : headA;
    }
    return a;
}

141. 环形链表

题目描述:
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
在这里插入图片描述

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

示例 2:
在这里插入图片描述

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

示例3:
在这里插入图片描述

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

代码:

public class Solution {
    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) {
                break;
            }
        }
        return fast != null && fast.next != null;
    }
}

问题:快慢指针为什么一定会相遇

慢指针每次移动一格,快指针每次移动两格,在有环的链表里,他们一定会相遇
1、当快指针就在慢指针后面,那么下一次慢指针移动一位,快指针移动两位,相遇
2、当快指针和慢指针差一个位置,那么下一次慢指针移动一位,快指针移动两位,他们会变成第一种情况
3、当快指针和慢指针差两个位置,那么下一次慢指针移动一位,快指针移动两位,他们会变成第二种情况
我知道你也在纠结为什么会没有快指针跳过慢指针他们没有相遇的这种情况发生,但是这种情况只会发生在他们相遇后的下一次移动
原因:其实从上面的三步不难看出:快指针是一格一格追赶慢指针的,即他们的距离是…4->3->2->1->0这样缩短的。所以一定会相遇

在这里插入图片描述

快慢指针为什么一定会相遇(文章参考):https://blog.csdn.net/Leslie5205912/article/details/89386769

142. 环形链表 II

题目描述:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
**说明:**不允许修改给定的链表。

示例 1:
在这里插入图片描述

输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:
在这里插入图片描述

输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:
在这里插入图片描述

输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。

代码:

public class Solution {
    static ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                break;
            }
        }
        //无环
        if (fast == null || fast.next == null) {
            return null;
        }

        //有环 这时候起点至入口的距离等于相交点至入口的距离,因此两个指针用同样的速度直到相遇就是入口
        slow = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return fast;
    }
}

问题:如何确认入口

在这里插入图片描述

如图:
慢指针走了 x+y 的距离
快指针走了 x+y+n(y+z)的距离
由于快指针是慢指针的二倍速度,因此得出公式
2(x+y) = x+y+n(y+z)
x = n(y+z)-y //放出去一个x+y
x = (n-1)(y+z)+z //n至少等于1,当n=1的时候可以推导出 x=z
因此,当两个指针用同样的速度走,相遇点就是入口

具体详解视频:https://www.bilibili.com/video/BV1if4y1d7ob

237. 删除链表中的节点

题目描述:
有一个单链表的 head,我们想删除它其中的一个节点 node。
给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。
链表的所有值都是 唯一的,并且保证给定的节点 node 不是链表中的最后一个节点。
删除给定的节点。注意,删除节点并不是指从内存中删除它。这里的意思是:

给定节点的值不应该存在于链表中。
链表中的节点数应该减少 1。
node 前面的所有值顺序相同。
node 后面的所有值顺序相同。

示例:1
在这里插入图片描述

输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9

示例:2
在这里插入图片描述

输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9

代码:

void deleteNode(ListNode node) {
    node.val = node.next.val;
    node.next = node.next.next;     
}

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

题目描述:
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例:1
在这里插入图片描述

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

示例:2

输入:head = [1], n = 1
输出:[]

示例:3

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

代码:

static ListNode removeNthFromEnd(ListNode head, int n) {
	//给出一个虚拟头指针,方便后期操作
    ListNode dummy = new ListNode(0);
    dummy.next = head;

    //fast先往前走n步
    ListNode fast = dummy;
    for (int i = 0; i < n; i++) {
        fast = fast.next;
    }

    //fast slow同步往前走,直到fast走到了null,这时候slow指向被删除节点的前一个节点
    ListNode slow = dummy;
    while (fast != null) {
        fast = fast.next;
        slow = slow.next;
    }
    
    slow.next = slow.next.next;

    return dummy.next;
}

21. 合并两个有序链表

题目描述:
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:1

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

代码:

static ListNode merge(ListNode l1, ListNode l2) {
     ListNode result = new ListNode(0);

     ListNode pre = result;
     while (l1 != null && l2 != null) {
         if (l1.val > l2.val) {
             pre.next = l2;
             l2 = l2.next;
         } else {
             pre.next = l1;
             l1 = l1.next;
         }
         pre = pre.next;
     }
     //如果两边长度不一致,剩下的则可以直接追加
     pre.next = l1 == null ? l2 : l1;

     return result.next;
 }

23. 合并K个升序链表(两种解法)

题目描述:
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:1

输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6

代码:(利用数组遍历找到最小值)
在这里插入图片描述

    static ListNode merge(ListNode[] listNodeArr) {
        ListNode result = new ListNode(0);
        ListNode cur = result;
        
        while (true) {
            int minIndex = -1;
            //找到最小索引
            for (int i = 0; i < listNodeArr.length; i++) {
                if (listNodeArr[i] != null) {
                    if (minIndex == -1) {
                        minIndex = i;
                    } else {
                        if (listNodeArr[i].val < listNodeArr[minIndex].val) {
                            minIndex = i;
                        }
                    }
                }
            }

            //如果minIndex:-1,证明数组中没有数据了
            if (minIndex == -1) {
                return result.next;
            }

            //result拼接当前最小节点
            cur.next = listNodeArr[minIndex];
            //cur后移
            cur = cur.next;

            //listNodeArr[minIndex]后移
            listNodeArr[minIndex] = listNodeArr[minIndex].next;
        }
    }

代码2:(利用小顶堆)

static ListNode merge2(ListNode[] listNodeArr) {
    //使用小顶堆,每次取出的都是最小的节点
    Queue<ListNode> minHeap = new PriorityQueue<>(Comparator.comparingInt(node -> node.val));
    ListNode result = new ListNode(0);
    ListNode cur = result;

    //将节点放进去
    for (ListNode list : listNodeArr) {
        if (list != null) {
            minHeap.offer(list);
        }
    }

    while (!minHeap.isEmpty()) {
        //弹出最小值
        ListNode tempNode = minHeap.poll();
        cur.next = tempNode;
        cur = cur.next;

        //往堆里放入当前节点的next
        if (tempNode.next != null) {
            minHeap.offer(tempNode.next);
        }
    }

    return result.next;
}

扩展:PriorityQueue

2. 两数相加

问题描述
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

代码

static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode head = new ListNode(0);//先给出一个节点,避免下面判断空,return head.next就好

    ListNode pre = head;
    int more = 0; //进位
    int sum = 0;//两个数字相加之和
    while (l1 != null || l2 != null || more != 0) {
        sum = (l1 != null ? l1.val : 0) + (l2 != null ? l2.val : 0) + more;
        more = sum / 10; //加出来的数字超过10,进一位
        sum = sum % 10; //加出来的数字值需要个位数

        //链表增加节点
        ListNode newNode = new ListNode(sum);
        pre.next = newNode;
        //pre指向当前最新节点,方便后面增加节点
        pre = newNode;

        //l1 l2都指向下一个节点,继续相加
        l1 = l1.next != null ? l1.next : null;
        l2 = l2.next != null ? l2.next : null;
    }
    return head.next;
}
  1. 环形链表 II(详解视频):https://www.bilibili.com/video/BV1if4y1d7ob
  2. 相交链表(详解视频):https://www.bilibili.com/video/BV1aK411N7fW
  3. 删除链表的倒数第 N 个结点(详解视频): https://www.bilibili.com/video/BV1fq4y1y7z3
  4. 合并两个有序链表(视频讲解): https://www.bilibili.com/video/BV1vo4y1Q7Ew
  5. 合并K个有序链表(视频讲解):https://www.bilibili.com/video/BV1QK4y1N7ww
  6. 两数相加(视频讲解):https://www.bilibili.com/video/BV11C4y1t7iY
  7. 分隔链表(视频讲解):https://www.bilibili.com/video/BV1Gq4y1e7GH
  8. 链表的中间结点(视频讲解):https://www.bilibili.com/video/BV1UK411n7RN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/117048.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【记忆增强深度条件展开网络】

Memory-augmented Deep Conditional Unfolding Network for Pan-sharpening &#xff08;面向全色锐化的记忆增强深度条件展开网络&#xff09; 全色锐化旨在为遥感系统获取高分辨率的多光谱图像&#xff0c;基于深度学习的方法已经取得了显著的成功。然而&#xff0c;大多数…

使用iServer rest api如何实现构建巷道效果

作者&#xff1a;刘大 背景 在实际生产环境中&#xff0c;特别是在采矿&#xff0c;公路建设项目上&#xff0c;我们往往会接触下图所示的巷道&#xff0c;那么在Web端如何快速通过线数据构建巷道模型呢&#xff1f;下面我们来详细说下 使用方式 第一步&#xff1a; 在iServe…

反垃圾邮件系统|基于Springboot+vue 实现反垃圾邮件系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

servlet(二)文件的上传

servlet实现文件的上传 文件上传是一个web应用常见的功能 比如&#xff1a;QQ头像&#xff0c;就使用了上传。 邮箱中也有附件的上传和下载功能。 OA系统中审批有附件材料的上传。 1.1前端需要有个form表单标签 methodpost请求 (因为post请求是没有长度限制&#xff0c;get…

Computer Graphics From Scratch - Chapter 7

系列文章目录 简介&#xff1a;Computer Graphics From Scratch-《从零开始的计算机图形学》简介 第一章: Computer Graphics From Scratch - Chapter 1 介绍性概念 第二章&#xff1a;Computer Graphics From Scratch - Chapter 2 基本光线追踪 第三章&#xff1a;Computer Gr…

新生儿喝奶后不要马上放回床上睡觉,为宝宝健康着想,先做1件事

看到一个问题&#xff0c;题主问&#xff0c;新生儿喝完奶能马上放回床上睡觉吗&#xff1f;可以吗&#xff1f;也许每个人都认为照顾新生儿是一件非常简单的事情&#xff0c;因为新生儿几乎整天都在睡觉。当他们饿的时候&#xff0c;他们会让他们的宝宝吃牛奶。他们吃饱了就要…

博客搭建教程(一):静态博客 GitHub + Gridea

同步blog文章 注册一个 Github 账号并创建仓库 注册Github账号 如果你没有 Github 的账号&#xff0c;那么可以进入 官网 开始注册&#xff08;注意一下用户名的填写&#xff0c;如果不使用自定义域名&#xff0c;用户名将会是你的 Github 分配给你的域名&#xff0c;例如你的…

D. George and Interesting Graph(最大匹配)

Problem - 387D - Codeforces 乔治喜欢图表。最重要的是&#xff0c;他喜欢有趣的图。我们将假设一个有向图是有趣的&#xff0c;如果它符合以下标准。 该图不包含任何多弧。 有一个顶点v&#xff08;我们称她为中心&#xff09;&#xff0c;这样对于图形u的任何顶点&#xff…

信息网络传播视听节目服务单位的设立与经营

一、行业准入 &#xff08;一&#xff09;网络视听业务准入范围 利用公共互联网&#xff08;含移动互联网&#xff09;向计算机、手机用户提供视听节目服务&#xff08;不含交互式网络电视&#xff08;IPTV&#xff09;、互联网电视、专网手机电视业务&#xff09;业务的&…

几个小设置让 mac 更好用

今天在 youtube 上看到一个视频[1]&#xff0c;讲新 mac 到手后一定要做的几个设置&#xff0c;有几个之前我不知道的小设置&#xff0c;非常好用&#xff0c;看完马上就用上了。一些常用的就不列了&#xff0c;比如说设置点按、三指拖拽&#xff0c;不知道的可以去搜索了解&am…

【Python数据可视化】使用geoplotlib绘制地理空间数据

geoplotlib前言一、安装geoplotlib包二、读取csv数据使用1.点密度可视化2.直方图3. Voronoi图总结前言 ❤️❤️希望大家能多多点赞。❤️❤️ 需要数据集的可以评论。 Geoplotlib 是地理空间数据可视化的开源Python库&#xff0c;包含了大量的地理空间可视化操作&#xff0c…

131. 分割回文串

131. 分割回文串 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 示例 1&#xff1a; 输入&#xff1a;s “aab” 输出&#xff1a;[[“a”,“a”,“b”]…

青少年等级考试【Python通关干货】(二级)

青少年等级考试【Python通关干货】(二级)1.列表类型的概念 2.序列的通用操作 3.可变序列及列表的通用操作 4.列表的特有操作 5.元组类型的概念与操作

激活学习:一种挑战反向传播的生物启发算法

激活学习(activation learning)是一种生物启发的简单本地学习规则构建的前向无监督通用模型&#xff0c;它的核心是构建多层神经网络使得网络输出激活强度能反映输入的相对概率大小。并且&#xff0c;它在一些任务上达到并超过反向传播的表现。激活学习的概念由山东大学教授周洪…

C++11标准模板(STL)- 算法(std::adjacent_difference)

定义于头文件 <algorithm> 算法库提供大量用途的函数&#xff08;例如查找、排序、计数、操作&#xff09;&#xff0c;它们在元素范围上操作。注意范围定义为 [first, last) &#xff0c;其中 last 指代要查询或修改的最后元素的后一个元素。 计算范围内各相邻元素之间…

MyBatis 配置文件解析

MyBatis 的核心配置文件是 mybatis-config.xml。注意配置文件中节点的顺序有要求&#xff0c;必须按照下面的顺序填写节点信息&#xff1a; (properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,reflectorFactory,plugins,environments,databa…

Odoo丨如何在Odoo中修改HTML编辑工具栏?

文章目录一、前言二、渲染原理三、修改方法一、前言 在odoo中&#xff0c;当我们在页面上使用Html类型或者html的小组件的时候&#xff0c;页面渲染成如下格式&#xff0c;供用户编辑⬇ 上方有一些工具栏如背景颜色&#xff0c;字体颜色&#xff0c;字体大小&#xff0c;插入表…

【Linux04-进程概念下】不愧是操作系统,优美的设计!

前言 上期的分享让我们知道进程大概的模样&#xff0c;本期一样重要&#xff0c;能学到操作系统设计的优美&#xff0c;体会到前辈们的智慧。 #环境变量 是什么 OS提供&#xff0c;往往有特殊功能的全局变量&#xff08;/etc/profile.d是设置环境变量的目录&#xff09; [b…

React 入门:实战案例 Github搜索_axios发送请求

文章目录快速搭建 API 服务器在 Search 组件中实现 Axios 发送请求在 App 组件中管理 List 组件的用户列表状态在 List 组件中更新渲染用户列表数据优化完善完整源码最终效果&#xff1a;快速搭建 API 服务器 根据下面步骤来操作&#xff0c;就可以快速搭建一个符合本案例使用…

明年跨境电商外贸的新增量在哪里?来自专家的2个判断

明年跨境电商外贸的新增量在哪里&#xff1f;来自专家的2个判断2022年&#xff0c;外贸大环境不容易&#xff0c;外贸人也不容易。自2021年9月以来&#xff0c;海运费飙涨&#xff0c;库容一降再降。大批的货品滞留库存&#xff0c;部分卖家只好硬着头皮扛下来了高额的仓储费&a…