剑指offer:13-16题_切片

第13题:调整数组顺序使奇数位于偶数前面
题目说明:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
程序

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        # write code here
        result_odd = []#奇数
        result_even = []#偶数
        for i in range(len(array)):
            if(array[i] % 2 != 0):
                result_odd.append(array[i])
            else:
                result_even.append(array[i])
        result = result_odd + result_even
        return result

知识点
1.合并两个列表

a = [1, 2, 3]
b = [4, 5, 6]
c = a + b

2.列表推导式
[表达式 for 变量 in 序列或可迭代对象 if 条件表达式]
举例:

print([i**2 for i in range(6)])#[0, 1, 4, 9, 16, 25]
l = [1, 2, 3, 4, 5, 6]
print(x**2 for i in l if x > 3)#[16, 25, 36]
print(dict({(i, i+2) for i in l}))#{1: 3, 4: 6, 6: 8, 5: 7, 2: 4, 3: 5}#字典
#实现嵌套列表的平铺
vec = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print([num for elem in vec for num in elem])#[1, 2, 3, 4, 5, 6, 7, 8, 9]

拓展题目:
1.
题目说明:共64个小格子,在第一个格子里放1粒米,第二个格子里放2粒米,第三个格子里放4粒米,第四个格子里放8粒米,以此类推,后面每个格子里的米都是前一个格子里的2倍,一直把64个格子都放满,那么到底需要多少粒米呢?
程序

print(sum([pow(2, i) for i in range(64)]))#18446744073709551615

题目说明:输出100以内的所有素数
程序
(1)

def isPrime(num):
	for i in range(2, num):
		if num % i == 0:
			return False
	return True

for i in range(2, 101):
	if isPrime(i):
		print(i)
#[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

(2)列表推导式

print([prime for prime in range(2, 101) if 0 not in [prime % num for num in range(2, prime-1)]])

第14题:链表中倒数第k个结点
题目说明:输入一个链表,输出该链表中倒数第k个结点。
程序
将结点放在列表里

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        # write code here
        l = []
        while head:
            l.append(head)
            head = head.next
        if k > len(l) or k < 1:
            return
        return l[-k]

设置两个指针,p1和p2,先让p2走k-1步,然后再一起走,当p2指向最后一个结点,那么,p1指向第k个结点

class Solution:
    def FindKthToTail(self, head, k):
        # write code here
        if head == None or k <= 0:
            return None
        p2 = head
        p1 = head
        #p2先走,走k-1步,如果k大于链表长度则返回空,否则的话继续走
        while k>1:
            if p2.next != None:
                p2 = p2.next
                k -= 1
            else:
                return None
		#两个指针一起走,一直到p2为最后一个,p1即为所求
        while p2.next != None:
            p1 = p1.next
            p2 = p2.next
        return p1

知识点
python实现链表
numpy数组切片操作
通过冒号分隔切片参数**start:stop:step(左闭右开)**来进行切片操作:

b = a[2:7:2]#从索引2开始到索引7停止,步长为2

冒号的解释:如果放置一个参数,例如:[2],将返回与该索引对应的单个元素;如果为[2:],将返回从索引2开始到末尾的子数组;如果为[:2],将返回从开头到索引2(不包括2)为止的子数组;如果使用了两个参数,例如:[2:7],将返回从索引2开始到7停止(不包括7)的子数组。
一维数组:

import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8])#构建一维数组
print(a[7])#8
print(a[7:])#[8]
print(a[:2])#[1, 2]
print(a[1:5])#[2, 3, 4, 5]
print(a[1:5:2])#[2, 4]

二维数组:
单个参数:返回行,例如a[8];一般地,a[a:b, c:d],此处逗号为分隔符,逗号之前为行操作,逗号之后为列操作。

import numpy as np
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print(a[1])#2 输出:[3, 4, 5] 等同于:print(a[1,])
print(a[1:])#1行到第3 等同于:print(a[1:,])
#[[3 4 5]
# [4 5 6]]
print(a[:,1])#1 输出:[2 4 5]
print(a[:,0:2])#1列到第2
#[[1 2]
# [3 4]
# [4 5]]
print(a[:,])#输出等个数组 等价于print(a)/print(a[:, :])

以下写法错误(逗号写在前面错误):

print(a[,:])
print(a[,])

-1:指最后一行/列,-2、-3以此类推
在这里插入图片描述

print(a[:, -1])#最后1 输出:[3 5 6] 等价于print(a[:, 2])
print(a[:, -2:-1])#倒数第2(二维数组)
#[[2]
# [4]
# [5]]

参考博客:切片操作
第15题:反转链表
题目说明:输入一个链表,反转链表后,输出新链表的表头。
程序
看图理解单链表的反转
使用3个指针遍历单链表,逐个结点点进行反转

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        if pHead == None:
            return None
        p = pHead
        q = p.next
        p.next = None
        while(q):
            r = q.next
            q.next = p
            p = q
            q = r
        return p

尾插法:从第2个节点到第n个节点,依次将节点插入到第1个节点(pHead节点)之后,最后将第一个节点挪到新表的表尾

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        if not pHead:
            return pHead
        if not pHead.next:#只有一个结点,直接返回
            return pHead
        p = pHead.next
        while p.next:
            q = p.next
            p.next = q.next
            q.next = pHead.next
            pHead.next = q
        p.next = pHead#成环
        pHead = p.next.next#新head变为原head的next
        p.next.next = None#从环变为单链表
        return pHead

第16题:合并两个排序的链表
题目说明:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
程序

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        # write code here
        p = new_p = ListNode(0)#头结点
        while pHead1 and pHead2:
            if pHead1.val <= pHead2.val:
                new_p.next = pHead1
                pHead1 = pHead1.next
            else:
                new_p.next = pHead2
                pHead2 = pHead2.next
            new_p = new_p.next
        if pHead1:#等价于:new_p.next = pHead1 or pHead2
            new_p.next = pHead1
        elif pHead2:
            new_p.next = pHead2
        return p.next#p为头结点

参考链接:剑指offer

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值