写出一段代码将链表中的两个节点位置互换位置_leetcode刷题(十一):链表

054e052901d19370f6c12ccee2382767.png

今天来讲一下链表大家族:

链表主要分为顺序存储结构以及链式存储结构,其中链式存储结构又可以分为单链表静态链表循环链表以及双向链表

先来讲讲顺序存储结构

简单来讲,顺序存储结构,就是一段地址连续的存储单元依次存储线性表的数据元素。

那么他又那些优缺点呢?首先是缺点,因为是顺序结构嘛,在插入和删除的时候,前面做插入删除动作时候,后面的元素是否要依次做出后退或者前进一位的当作?是不是很麻烦!

在最糟糕的情况下,第一位插入或者删除一位,那么时间复杂度就会飙到O(n),容易造成存储的碎片。

当然了,优点也是有的,比如无需为表中元素之间的逻辑关系而增加额外的外储空间。同时因为是顺序结构,所以可以快速存取表中任一位置的元素。

再来讲讲链式存储结构

上面说到了,顺序存储最大的缺点就是插入和删除需要移动大量元素,很浪费时间。呢么有没有好点的办法来解决呢?

这里就是引进链式存储了,我们不必去纠结元素之间的相邻位置了,我们直接告诉上个元素下个元素的位置数据不就行了!

为了表示每个数据元素ai与其直接后继数据元素ai+ 1之间的逻辑关系。对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其后继的信息(即直接后继的存储位置)。我们把存储数据元素信息的域称为数据域,把存储后继的位置的域称为指针域.指针域中存储的信息称做指针.这两部分信息组成的元素ai的存储映像,称为结点

n个结点(ai的存储映像)链结成一个链表,即为线性表(a1,a2,...an)的链式存储结构,因为此链表的每个结点中只包含一个指针域,所有叫做单链表

这里要将一个小tip:单链表插入和删除

插入:s->next = p->next , p->next = s

删除:q = p->next , p->next = q->next

那么问题来了,为什么要这么写呢?如果将两句的顺序调换一下可不可以呢?

我们来对比下单链结构和顺序存储结构的优缺点吧:

存储分配方式

顺序存储用一段连续的存储单元依次存储线性表的数据元素

单链表采用链式存储结构,用一组任意的存储单元存放线性表元素

时间性能

查找:

顺序存储O(1)

单链表O(n)

插入和删除:

顺序存储平均需要移动表长一半的元素 时间为0(n)

单链表在计算出某位置的指针后,插入和删除时间仅为O(1)

空间性能

顺序存储结构需要预分配存储空间,分大了,容易造成空间浪费,分小了,容易发生溢出

单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制

下面简单讲讲其他链式存储方式:

静态链表

用数组描述的链表,即称为静态链表。

优点:再插入和删除时候,只需要修改游标,不需要移动元素,从而改进了顺序存储结构中插入和删除操作需要移动大量元素的缺点。

缺点:没有解决连续存储分配带来的表长难以确定的问题;失去了顺序存储结构随机存取的特性。

链表家族成员差不多就介绍到这里了,下面是真题时间。

160. 相交链表

编写一个程序,找到两个单链表相交的起始节点。

如下面的两个链表:

ae884151ab5c5e74179ec4f8c4936a70.png

在节点 c1 开始相交。

7293871afa57e70039d82b13178b785d.png

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3

输出:Reference of the node with value = 8

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

这题比较有趣,我先简单说说。

主要两种思维:

1.先算出A和B的长度,算出长度差n,先让长的跑n步,然后再一起跑,只要是相同就找到intersectVal啦

2.A和B一起走,短的一个,比方说A先到底了,就把指针指向B的头,B走到底后把指针指向A的头,这样走下来两个指针走的路长短都是相同的,而且只要有相同的地方,两个指针必然会C1处相遇。

下面代码选用了第二种思维

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        a = headA
        b = headB
        while(a != b):
            a = headB if a == None else a.next
            b = headA if b == None else b.next
        return a

206. 反转链表

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL

输出: 5->4->3->2->1->NULL

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        p = head
        rev = None
        while p:
            rev, rev.next, p = p, rev, p.next
        return rev

这段代码妙不可言,利用了多元赋值的时候,右边的值不会随着赋值而改变的特性,下面有解释可以看看

前置条件:迭代指针:p = head、结果指针:res = none

以1->2->3->4->5为例:

过程:

res:None

第一层循环

res:1->2->3->4->5 res = p

res:1->None res.next = res

p:2->3->4->5 p = p.next

第二层循环

res:2->3->4->5 res = p

res:2->1->None res.next = res

p:3->4->5 p = p.next

第三层循环

res:3->4->5 res = p

res:3->2->1->None res.next = res

p:4->5 p = p.next

第四层循环

res:4->5 res = p

res:4->3->2->1->None res.next = res

p:5 p = p.next

第五层循环

res:5 res = p

res:5->4->3->2->1->None res.next = res

p:None p = p.next

end...

234. 回文链表

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2

输出: false

示例 2:

输入: 1->2->2->1

输出: true

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if head == None:
            return True
        p = head
        val = []
        while(p != None):
            val.append(p.val)
            p = p.next
        return val == val[::-1]

83. 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:

输入: 1->1->2

输出: 1->2

示例 2:

输入: 1->1->2->3->3

输出: 1->2->3

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def deleteDuplicates(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        prev = head
        curr = head
        form = set()
        while curr is not None:
            if curr.val not in form:
                form.add(curr.val)
                prev = curr
            else:
                prev.next = curr.next 
            curr = curr.next
        return head

希望本文能帮到你!~!

最后打个小广告,我的公众号,喜欢写点学习中的小心得,不介意可以关注下!~!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值