Leetcode刷题(21) 链表反转系列

Leetcode刷题(21) 链表反转系列,数组的旋转

206. 反转链表

集体方法参考labuladong的递归反转链表的一部分,文本是用python的实现

方法一:递归反转整个链表

# 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
        """
        # base case
        if head == None:
            return None
        # base case
        if head.next == None:
            return head
        last = self.reverseList(head.next)
        # reverse
        head.next.next = head
        # 被反转的node的next先指向null
        head.next = None
        return last 

方法二:迭代反转整个链表

# 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
        cur = head
        nxt = head
        pre = None
        while(cur!=None):
            # 记录下一个要反转的node
            nxt = cur.next
            # 反转当前的node
            cur.next = pre
            # 更新pre and cur用于下次的反转
            pre = cur
            cur = nxt
        return pre

92. 反转链表 II

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

class Solution(object):
    def __init__(self):
        self.suc = None
    def reverseBetween(self, head, m, n):
        """
        :type head: ListNode
        :type m: int
        :type n: int
        :rtype: ListNode
        """
        # 反转前n个节点
        def reverseN(head, n):
            if n == 1:
                self.suc = head.next
                return head
            last = reverseN(head.next, n - 1)
            head.next.next = head
            head.next = self.suc
            return last

        # base case
        if m == 1:
            return reverseN(head, n)
        # 不断递归直到触发了basecase m == 1
        head.next = self.reverseBetween(head.next, m-1, n-1)
        return head
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reverseBetween(self, head, m, n):
        """
        :type head: ListNode
        :type m: int
        :type n: int
        :rtype: ListNode
        """
        def reverse(a, b):

            pre = b
            cur = a
            while(cur != b):
                nxt = cur.next
                cur.next = pre
                pre = cur
                cur =nxt
            return pre
        
        if m == 1:
            b = head
            for i in range(n):
                b = b.next
            return reverse(head, b)
        else:
            head.next = self.reverseBetween(head.next, m - 1, n - 1)
        return head

        

具体方法参考labuladong的如何k个一组反转链表,文本是用python的实现

25. K 个一组翻转链表

reverse(a, b)使用的是迭代的方法,在开区间[a, b)中反转链表,reverseKGroup(a, k)使用的是递归的方法。

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

class Solution(object):
    def reverseKGroup(self, head, k):
        """
        :type head: ListNode
        :type k: int
        :rtype: ListNode
        """
        def reverse(a, b):
            pre = None
            cur = a
            nxt = a
            while(cur != b):
                # 记录下当前要翻转节点的next
                nxt = cur.next
                # 翻转当前节点
                cur.next = pre
                # update cur and pre
                pre = cur
                cur = nxt
            return pre

        if head == None:
            return None
        a = head
        b = head
        for i in range(0, k):
            # 剩下的node不满足k个直接返回当前的head不做反转
            if b == None:
                return head
            b = b.next

        newHead = reverse(a, b)
        # a作为组中新的最后一个节点, next指向后继, 也就是下一组的newHead
        a.next = self.reverseKGroup(b, k)
        # head.next = self.reverseKGroup(b, k)
        return newHead




189. 旋转数组

这题是数组的旋转, 不好放哪我就放在这个部分了

暴力法:一次一次的原地旋转,旋转k次

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        # 一次一次旋转, 旋转k次
        for i in range(k):
            # pre是用来记录将要用于去替换下一个位置的元素的元素
            pre = nums[n - 1]
            for j in range(n):
                tmp = nums[j]
                nums[j] = pre
                pre = tmp

新建一个数组来辅助,一次性定位到每个元素的指定位置

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        # 一次一次旋转, 旋转k次
        for i in range(k):
            # pre是用来记录将要用于去替换下一个位置的元素的元素
            pre = nums[n - 1]
            for j in range(n):
                tmp = nums[j]
                nums[j] = pre
                pre = tmp

华为机试2020.08.26 的第一题题解, 有点像上一题:

import sys
def main():
    sys.stdin = open('input.txt', 'r')
    lines = sys.stdin.readlines()
    n = len(lines)
    index = 0
    while index < n:
        line = list(map(int, lines[index].strip().split()))
        nums = []

        for num in line:
            num = list(bin(num)[2:].zfill(32))
            i = 0
            while i < 32:
                tmp = num[i]
                num[i] = num[i + 1]
                num[i + 1] = tmp
                i += 2
            nums.append(num)

        _1 = '0'
        _2 = '0'
        for i, num in enumerate(nums):
            if i == 0:
                num.insert(0, '0')
                num.insert(0, '0')
                _1 = num.pop()
                _2 = num.pop()
                nums[i] = num
            else:
                num.insert(0, _1)
                num.insert(0, _2)
                _1 = num.pop()
                _2 = num.pop()
                nums[i] = num

        # 最后处理第一个数
        nums[0][0] = _2
        nums[0][1] = _1

        l = len(nums)
        for i, num in enumerate(nums):
            if i < l - 1:
                print(int(''.join(num), base=2), end=" ")
            else:
                print(int(''.join(num), base=2))

        index += 1


if __name__ == "__main__":
    main()

234. 回文链表

递归判断

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

class Solution(object):
    def __init__(self):
        self.left = None

    def isPalindrome(self, head):
        self.left = head
        """
        :type head: ListNode
        :rtype: bool
        """
        def isp(head):
            if head == None:
                return True
            res = isp(head.next)
            res = res and head.val == self.left.val
            self.left = self.left.next
            return res

        return isp(head)

用快慢指针找到中点,然后从中点开始反转链表,再逐个进行比较

# 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
        """
        def reverse(root):
            cur = root
            pre = None
            while(cur!=None):
                nxt = cur.next

                cur.next = pre

                pre = cur
                cur = nxt
            return pre
            
        def findMid():
            slow = head
            fast = head
            while (fast!=None and fast.next!=None):
                slow = slow.next
                fast = fast.next.next
            if fast != None:
                slow = slow.next
            return slow

        left = head
        mid = findMid()
        right = reverse(mid)

        while right!=None:
            if left.val != right.val:
                return False
            left = left.next
            right = right.next
        return True

189. 旋转数组

撑杆跳法

class Solution(object):
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        k = k % n
        count = 0
        start = 0
        # count是用来控制循环的
        while count < n:
            current = start
            prev = nums[start]
            # 使用flag的原因是为了让第一次循环可以进行
            flag = 0
            while start != current or flag == 0:
                flag = 1
                nxt = (current + k) % n
                temp = nums[nxt]
                # 撑杆跳
                nums[nxt] = prev
                # 更新prev和current
                prev = temp
                current = nxt
                # 记录已经移动了几个元素
                count += 1
            # start移动到下一位
            start += 1
                
            
        

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值