递增的整数序列链表的插入_常见数据结构算法(链表篇)

eb871eb87a970ec5e7348ebbb7fbdd2d.png
  1. 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路:

  • 由于数组具有从左到右递增,从上到下递增的规律,这时候应该考虑从左下或者右上方进行与目标值的大小比较,以右上方为例,若右上方元素大于目标值,则减少列,此时若小于目标值,则增加行,以此类推。具体代码实现如下(时间复杂度为O(row+col)):
# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        row = len(array)
        col = len(array[0])
        if row == 0 or col == 0:
            return False
        if target < array[0][0] or target > array[row-1][col-1]:
            return False
        i = 0
        j = col-1
        while i <= row and j >= 0:
            if target < array[i][j]:
                j -= 1
            elif target > array[i][j]:
                i +=1
            else:
                return True
        return False

2. 输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

思路:

  • 可以通过构造一个栈空间来让先进的元素后出去(时间复杂度为O(n))
# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # 返回从尾部到头部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # write code here
        if listNode == None:
            return []
        ret = []
        while listNode:
            ret.insert(0, listNode.val)
            listNode = listNode.next
        return ret

3. 单链表反转。

思路:

  • 关键是确定好一个prev、curr节点,然后逐步将curr的next指向prev(时间复杂度为O(n))
# 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
        """
        if head == None:
            return None
        prev = None
        curr = head
        while curr != None:
            tmp = curr.next
            curr.next = prev
            prev = curr
            curr = tmp
        return prev

4. 给定一个链表,每 k 个节点一组进行翻转,返回翻转后的链表。

思路:

  • 链表分区为已翻转部分+待翻转部分+未翻转部分
  • 每次翻转前,要确定翻转链表的范围,这个通过 k 次循环来确定
  • 需记录翻转链表前驱和后继,方便翻转完成后把已翻转部分和未翻转部分连接起来
  • 初始需要两个变量 pre 和 end,pre 代表待翻转链表的前驱,end 代表待翻转链表的末尾
  • 经过k此循环,end 到达末尾,记录待翻转链表的后继 next = end.next
  • 翻转链表,然后将三部分链表连接起来,然后重置 pre 和 end 指针,然后进入下一次循环
  • 特殊情况,当翻转部分长度不足 k 时,在定位 end 完成后,end==null,已经到达末尾,说明题目已完成,直接返回即可
  • 时间复杂度为 O(n*K)O(n∗K) 最好的情况为 O(n),最差的情况为O(n^2)
  • 空间复杂度为 O(1),除了几个必须的节点指针外,没有占用其他空间
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):

    def reverse(self, head, tail):
        prev = tail.next
        p = head
        while prev != tail:
            nex = p.next
            p.next = prev
            prev = p
            p = nex
        return tail, head

    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        hair = ListNode(0)
        hair.next = head
        pre = hair

        while head:
            tail = pre
            # 查看剩余部分长度是否大于等于 k
            for i in range(k):
                tail = tail.next
                if not tail:
                    return hair.next
            nex = tail.next
            head, tail = self.reverse(head, tail)
            # 把子链表重新接回原链表
            pre.next = head
            tail.next = nex
            pre = tail
            head = tail.next
        
        return hair.next
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值