算法0308

目录

1.数组中只有012,排序(0413)

  • 题目:
  • 代码:
def sort012(arr):
	if len(arr) == 0:
    	return None
    elif len(arr) == 1:
        return arr
    elif len(arr) == 2:
        if arr[0]>arr[1]:
            return arr[::-1]
    p0 = 0
    p2 = len(arr)-1
    p1 = 0
    while arr[p0] == 0:
        p0 += 1
    p1 = p0
    while arr[p2] == 2:
        p2 -= 1
    while p1 <= p2:
        if arr[p1] == 1:
            p1 += 1
        elif arr[p1] == 0:
            arr[p0], arr[p1] = arr[p1], arr[p0]
            while arr[p0] == 0:
                p0 += 1
        elif arr[p1] == 2:
            arr[p2], arr[p1] = arr[p1], arr[p2]
            while arr[p2] == 2:
                p2 -= 1
    return arr
  • 思想:
    设置三个指针,p0代表0,p1代表1,p2代表2,p0从数组开头向后遍历,遇到为0的就往后移动,直到遇到第一个不为1的数,停下,然后将p1指向这个数字,p2从数组末尾像前遍历,直到遇到不为2的数,停下。然后当指针p1小于等于p2时,就开始比较:
    如果p1为1,就也一直向后遍历。
    如果p1指向数字0,则将arr[p1]与arr[p0]交换位置,然后p0开始继续遍历直到遇到不为0的数,再停下。
    如果p1指向数字2,则将arr[p2]与arr[p1]交换位置,然后p2开始继续遍历直到遇到不为2的数,再停下。
    最后返回数组。

2.根据字符出现频率排序(0308)

  • 题目:给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
示例:
输入:
"tree"
输出:
"eert"
解释:
'e'出现两次,'r''t'都只出现一次。
因此'e'必须出现在'r''t'之前。此外,"eetr"也是一个有效的答案。
  • 代码:
class Solution(object):
    def frequencySort(self, s):
        d={}
        for i in range(len(s)):
            if s[i] in d:
                d[s[i]] += 1
            else:
                d[s[i]] = 1
        list = zip(d.values(), d.keys())
        list.sort(reverse=True)
        res = ""
        for i in range(len(list)):
            res += list[i][1]*list[i][0]
        return res
  • 思想:
    定义一个字典,从字符串中第一个元素开始寻找,如果其已经为字典的某个key,则此key的valve加一,如果其不在字典d内,则定义其为字典d的一个key,其值为1。遍历整个字符串后。将字典d的键值对打包成一个个元组组成的列表。然后根据列表中每个元组的第一位元组将列表中的元组进行降序排序。然后遍历此列表,将每个元素通过出现的次数依次还原回来。

  • 备注:

  1. list.sort(reverse=True)
    reverse作用决定是降序还是升序排列,reverse=True为降序,reverse=False为升序

  2. Python zip() 函数

  • 描述:
    zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。
  • 例:
a = [1,2,3]
b = [4,5,6]
zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]

https://leetcode-cn.com/problems/sort-characters-by-frequency/

https://blog.csdn.net/weixin_42234472/article/details/85220525?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control

3.翻转单词间的顺序(0309)

  • 题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。
  • 代码:
class Solution(object):
    def reverseWords(self, s):
        s = s.strip() # 删除首尾空格
        i = j = len(s) - 1
        res = []
        while i >= 0:
            while i >= 0 and s[i] != ' ': i -= 1 # 搜索首个空格
            res.append(s[i + 1: j + 1]) # 添加单词
            while s[i] == ' ': i -= 1 # 跳过单词间空格
            j = i # j 指向下个单词的尾字符
        return ' '.join(res) # 拼接并返回
  • 思想:双指针
    倒序遍历字符串 s ,首先清除字符串左右空字符,指针 j 放在字符串末尾,指针 i从字符串末尾开始倒叙遍历字符串,直至遇到第一个空格,说明一个i与j之间为一个单词,将其s[i + 1: j + 1]放入单词列表res。i继续向前遍历,直至遇到不为空格的字符,将 j 移动到此位置。i继续向前遍历。。以此类推。最终,将单词列表拼接为字符串,并返回即可。
    复杂度分析:
    时间复杂度O(N) : 其中 N 为字符串 ss 的长度,线性遍历字符串。
    空间复杂度O(N) : 新建的 list(Python) 或 StringBuilder(Java) 中的字符串总长度 ≤N ,占用 O(N) 大小的额外空间。

  • 备注

  1. strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
    注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
    语法:str.strip([chars]);
    返回值:返回移除字符串头尾指定的字符生成的新字符串。
str1 = "00000003210Runoob01230000000"; 
print str1.strip( '0' );  # 去除首尾字符 0
str2 = "   Runoob      ";   # 去除首尾空格
print str2.strip();
  1. append() 方法用于在列表末尾添加新的对象。
    语法:
    list.append(obj)
    参数:
    obj – 添加到列表末尾的对象。
    返回值:
    该方法无返回值,但是会修改原来的列表。
aList = [123, 'xyz', 'zara', 'abc'];
aList.append( 2009 );
print "Updated List : ", aList;
以上实例输出结果如下:
Updated List :  [123, 'xyz', 'zara', 'abc', 2009]
  1. join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
    语法:
    str.join(sequence)
    参数:
    sequence – 要连接的元素序列。
    返回值:
    返回通过指定字符连接序列中元素后生成的新字符串。
s1 = "-"
s2 = ""
seq = ("r", "u", "n", "o", "o", "b") # 字符串序列
print (s1.join( seq ))
print (s2.join( seq ))
以上实例输出结果如下:
r-u-n-o-o-b
runoob
  1. Python中字符串切片方法
    字符串[开始索引:结束索引:步长]
    切取字符串为开始索引到结束索引-1内的字符串
    步长不指定时步长为1 字符串[开始索引:结束索引]
str="abcdefghijklmn"
str1=str[2:5]
print(str1)
#输出结果:cde 左闭右开

https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/mian-shi-ti-58-i-fan-zhuan-dan-ci-shun-xu-shuang-z/

4.翻转单词内部字母顺序(0323)

问题

  • 题目
    给定字符类型的数组chas,请在单词间做逆序调整。只要做到单词的顺序逆序即可,对空格的位置没有要求。
    示例1:输入:“i am a student”,输入:“i ma a tneduts”
  • 代码
def reverseOnlyLetters(S):
    stack = []
    res = []
    i = len(S)-1
    while i>=0:
        stack.append(S[i])
        i-=1
    stack = "".join(stack)
    i = j = len(stack)-1
    while i>=0:
        while i>=0 and stack[i]!=" ":
            i-=1
        res.append(stack[i+1:j+1])
        while stack[i]==" ":
            i-=1
        j = i
    return " ".join(res)
  • 思想
    首先把字符串逆序放入栈中,然后翻转单词顺序
  • 备注

5.数组中出现次数超过一半的数字(0310)

  • 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
  • 代码
class Solution(object):
    def majorityElement(self, nums):        
        votes, count = 0, 0 #votes为投票总数,count为x出现的次数用于验证数组中是否存在众数
        for num in nums:
            if votes == 0: 
                x = num   #x为众数
            if num == x:
                votes += 1 
            else:
                votes -= 1 
        # 验证 x 是否为众数
        for num in nums:
            if num == x: 
                count += 1
            if count > len(nums):
                return x 
            else:
                return 0 # 当无众数时返回 0
  • 思想
    投票法:
    如果把某出现次数多于数组一半的数出现一次票数+1 ,出现非众数票数−1 ,则所有数字的票数和> 0 。数组的前 a个数字的票数和=0 ,则数组剩余数字的票数和一定仍>0,也就是说众数一定在后面的数中。
    算法流程:
    初始化: 票数统计 votes = 0 , 设众数为x;
    循环: 遍历数组 nums 中的每个数字 num ;
    当 票数 votes 等于 0 ,则假设当前数字 num 是众数;
    当 num = x 时,票数 votes 自增 1 ;当 num != x 时,票数 votes 自减 1 ;
    返回值: 返回 x 即可;
  • 备注

https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/solution/mian-shi-ti-39-shu-zu-zhong-chu-xian-ci-shu-chao-3/

#字典映射方法,不是很好
class Solution(object):
    def majorityElement(self, nums):
        d={}
        for num in range(len(nums)-1):
            if nums[num] in d:
                d[nums[num]]+=1
            else:
                d[nums[num]]=1
        return max(d.keys(), key=d.get)

6.用栈实现队列(0311)

  • 题目:

  • 代码

class Solution:
    def __init__(self):
        self.stack_in = []
        self.stack_out = []
    def push(self, node):
        self.stack_in.append(node)
    def pop(self):
        if self.stack_out == []:
            while self.stack_in:
                self.stack_out.append(self.stack_in.pop())
        if self.stack_out:
            return self.stack_out.pop()
        else:
            return None
  • 思想
    stack_in只负责进入
    stack_out只负责取出
    只有stack_out为空时才把stack_in的所有元素倾倒进stack_out中,这样顺序就不会乱了

  • 备注

https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=117&tqId=37774&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

7.翻转链表(0312)

  • 题目
    输入一个链表,反转链表后,输出新链表的表头。
输入
{1,2,3}
返回值
{3,2,1}
  • 代码
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # write code here
        cur, pre = pHead, None
        while cur:
            tmp = cur.next # 暂存后继节点 cur.next
            cur.next = pre # 修改 next 引用指向
            pre = cur      # pre 暂存 cur
            cur = tmp      # cur 访问下一节点
        return pre
  • 思想
    首先使用指针记录当前节点的后继节点,然后将当前节点指向前一节点。然后将前一节点记录为当前节点,然后将当前节点指针后移一位,循环。

  • 备注

https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca?tpId=117&tqId=37777&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/solution/jian-zhi-offer-24-fan-zhuan-lian-biao-die-dai-di-2/

8.LRU 缓存机制(0412)

  • 题目
    运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制 。
    实现 LRUCache 类:
    LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
    int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
    void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
    示例:
输入
["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"]
[[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]]
输出
[null, null, null, 1, null, -1, null, -1, 3, 4]

解释
LRUCache lRUCache = new LRUCache(2);
lRUCache.put(1, 1); // 缓存是 {1=1}
lRUCache.put(2, 2); // 缓存是 {1=1, 2=2}
lRUCache.get(1);    // 返回 1
lRUCache.put(3, 3); // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3}
lRUCache.get(2);    // 返回 -1 (未找到)
lRUCache.put(4, 4); // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3}
lRUCache.get(1);    // 返回 -1 (未找到)
lRUCache.get(3);    // 返回 3
lRUCache.get(4);    // 返回 4
  • 代码
class DLinkedNode:
    def __init__(self,key = 0, value = 0):
        self.key = key
        self.value = value
        self.next = None
        self.prev = None

class LRUCache(object):

    def __init__(self, capacity):
        self.capacity = capacity
        self.head = DLinkedNode()
        self.tail = DLinkedNode()
        self.head.next = self.tail
        self.tail.prev = self.head
        self.cache = dict()
        self.size = 0


    def get(self, key):
        if key not in self.cache:
            return -1
        else:
            node = self.cache[key]
            self.removenode(node)
            self.addtohead(node)
            return node.value


    def put(self, key, value):
        if key not in self.cache:
            node = DLinkedNode(key, value)
            self.cache[key]=node
            self.addtohead(node)
            self.size+=1
            if self.size>self.capacity:
                remove = self.removetail()
                self.cache.pop(remove.key)
                self.size-=1
        else:
            node = self.cache[key]
            node.value = value
            self.removetail(node)
            self.addtohead(node)

    def addtohead(self, node):
        node.prev= self.head
        node.next= self.head.next
        self.head.next.prev = node
        self.head.next = node
    
    def removenode(self, node):
        node.prev.next = node.next
        node.next.prev = node.prev
    
    def removetail(self):
        node = self.tail.prev
        self.removenode(node)
        return node



# Your LRUCache object will be instantiated and called as such:
# obj = LRUCache(capacity)
# param_1 = obj.get(key)
# obj.put(key,value)
  • 思想:字典+双链表
    算法
    LRU 缓存机制可以通过哈希表辅以双向链表实现,我们用一个哈希表和一个双向链表维护所有在缓存中的键值对。
    双向链表按照被使用的顺序存储了这些键值对,靠近头部的键值对是最近使用的,而靠近尾部的键值对是最久未使用的。
    哈希表即为普通的哈希映射(HashMap),通过缓存数据的键映射到其在双向链表中的位置。
    首先使用哈希表进行定位,找出缓存项在双向链表中的位置,随后将其移动到双向链表的头部,即可在O(1) 的时间内完成 get 或者 put 操作。具体的方法如下:
    (1)对于 get 操作,首先判断 key 是否存在:
    如果 key 不存在,则返回 −1;
    如果 key 存在,则 key 对应的节点是最近被使用的节点。通过哈希表定位到该节点在双向链表中的位置,并将其移动到双向链表的头部,最后返回该节点的值。
    (2)对于 put 操作,首先判断 key 是否存在:
    如果 key 不存在,使用 key 和 value 创建一个新的节点,在双向链表的头部添加该节点,并将 key 和该节点添加进哈希表中。然后判断双向链表的节点数是否超出容量,如果超出容量,则删除双向链表的尾部节点,并删除哈希表中对应的项;
    如果 key 存在,则与 get 操作类似,先通过哈希表定位,再将对应的节点的值更新为 value,并将该节点移到双向链表的头部。

定义的addtohead和removenode方法中的顺序是不能变的,不然链表就断开了

  • 备注

https://www.nowcoder.com/practice/e3769a5f49894d49b871c09cadd13a61?tpId=117&tqId=37804&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/lru-cache/

9.判断链表中是否有环(0313)

  • 题目
    判断给定的链表中是否有环。如果有环则返回true,否则返回false。
  • 代码
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
# @param head ListNode类 
# @return bool布尔型
class Solution:
    def hasCycle(self , head ):
        if not head or not head.next:
               return False
        slow = head
        fast = head
        while fast and fast.next is not None:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False
  • 思想
    设置两个指针,一个快指针一个慢指针,初始时都在链表头部,然后快指针一次走两步,慢指针一次走一步,当两个指针汇合,就说明链表有环。
  • 备注
  • not x
    意思相当于 if x is false, then True, else False
    https://www.cnblogs.com/yymn/p/5576645.html

https://www.nowcoder.com/practice/650474f313294468a4ded3ce0f7898b9?tpId=117&tqId=37714&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/linked-list-cycle/

删除链表的倒数第n个节点

  • 题目:
    给定一个链表,删除链表的倒数第 nn 个节点并返回链表的头指针
    例如,
    给出的链表为: 1\to 2\to 3\to 4\to 51→2→3→4→5, n= 2n=2.
    删除了链表的倒数第 nn 个节点之后,链表变为1\to 2\to 3\to 51→2→3→5.
    备注:
    题目保证 nn 一定是有效的
    请给出请给出时间复杂度为\ O(n) O(n) 的算法
  • 代码:
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 
# @param head ListNode类 
# @param n int整型 
# @return ListNode类
#
class Solution:
    def removeNthFromEnd(self , head , n ):
        # write code here
        h = ListNode(0)
        h.next = head
        slow = fast = h
        for i in range(n):
            fast = fast.next
        while fast.next:
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next
        return h.next

-思想:
双指针,一个先走n步,然后两个指针一起走,直到先走的那个到头了,就说明这就是倒数第n个节点,后一个指针nextnext就好了。

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/san-chong-fang-fa-shan-chu-dao-shu-di-nge-jie-dian/

实现二叉树先序,中序和后序遍历(待解决)

  • 题目

  • 代码

  • 思想

  • 备注

https://www.nowcoder.com/practice/a9fec6c46a684ad5a3abd4e365a9d362?tpId=117&tqId=37819&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

10.最小的K个数(0315)

  • 题目
    给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。如果K>数组的长度,那么返回一个空的数组。
示例1
输入
[4,5,1,6,2,7,3,8],4
返回值
[1,2,3,4]
  • 代码
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # write code here
        if k>=len(tinput):
            return tinput
        def kuaisu(tinput,left,right):
            i = left
            j = right
            key = tinput[left]
            while i<j:
                while j>i and tinput[j]>key:
                    j-=1
                while i<j and tinput[i]<key:
                    i+=1
                tinput[i],tinput[j]=tinput[j],tinput[i]
            tinput[left]=tinput[i]
            tinput[i]=key
            if k>i:
                kuaisu(tinput,i+1,right)
            if k<i:
                kuaisu(tinput,left,i-1)
            return tinput[:k]
        return kuaisu(tinput,0,len(tinput)-1)
  • 思想
    基于快速排序的数组划分**(哨兵划分+递归)**
    题目只要求返回最小的 k 个数,对这 k 个数的顺序并没有要求。因此,只需要将数组划分为 最小的 k个数 和 其他数字 两部分即可,而快速排序的哨兵划分可完成此目标。
    根据快速排序原理,如果某次哨兵划分后 基准数正好是第k+1 小的数字 ,那么此时基准数左边的所有数字便是题目所求的 最小的 k 个数 。
    根据此思路,考虑在每次哨兵划分后,判断基准数在数组中的索引是否等于 k ,若 true 则直接返回此时数组的前k个数字即可。
    算法流程:
    getLeastNumbers() 函数:
    若 k大于数组长度,则直接返回整个数组;
    执行并返回 quick_sort() 即可;
    quick_sort() 函数:
    注意,此时 quick_sort() 的功能不是排序整个数组,而是搜索并返回最小的 kk 个数。
    哨兵划分:
    划分完毕后,基准数为 arr[i] ,左 / 右子数组区间分别为 [l, i - 1][l,i−1]
    递归或返回:
    若 k < ik<i ,代表第 k + 1k+1 小的数字在 左子数组 中,则递归左子数组;
    若 k > ik>i ,代表第 k + 1k+1 小的数字在 右子数组 中,则递归右子数组;
    若 k = ik=i ,代表此时 arr[k] 即为第 k + 1k+1 小的数字,则直接返回数组前 kk 个数字即可;

  • 备注

https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/solution/jian-zhi-offer-40-zui-xiao-de-k-ge-shu-j-9yze/

求二叉树的层序遍历(待解决)

  • 题目
    给定一个二叉树,返回该二叉树层序遍历的结果(从左到右,一层一层地遍历)
    例如:
给定的二叉树是{3,9,20,#,#,15,7},
该二叉树层序遍历的结果是
[
[3],
[9,20],
[15,7]
]
  • 代码

  • 思想

  • 备注

https://www.nowcoder.com/practice/04a5560e43e24e9db4595865dc9c63a3?tpId=117&tqId=37723&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

11.寻找第K大(0316)

  • 题目
    有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
    给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
示例1
输入
[1,3,5,2,2],5,3
返回值
2
  • 代码
class Solution:
    def findKth(self, a, n, K):
        if K > n:
            return None
        if K ==n:
            return a[K]
        # write code here
        def kuaisu(a,left,right,K):
            i = left
            j = right
            key = a[left]
            while i<j:
                while i<j and a[j]>=key:
                    j-=1
                while i<j and a[i]<=key:
                    i-=1
                a[i],a[j]=a[j],a[i]
            a[left] = a[i]
            a[i] = key
            dayukdegeshu = right-i
            if K - dayukdegeshu - 1<0:
                kuaisu(a,i+1,right)
            if K - dayukdegeshu - 1>0:
                kuaisu(a,left, i-1)
            return a[i]   
#         kuaisu( a, 0, n-1, K)
  • 思想
    快排思想
  • 备注

https://www.nowcoder.com/practice/e016ad9b7f0b45048c58a9f27ba618bf?tpId=117&tqId=37791&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

12.合并有序链表(0316)

  • 题目
    将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的,且合并后新链表依然有序。
示例1
输入
{1},{2}
返回值
{1,2}
  • 代码
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 
# @param l1 ListNode类 
# @param l2 ListNode类 
# @return ListNode类
#
class Solution:
    def mergeTwoLists(self , l1 , l2 ):
        # write code here
        preHead =  ListNode(-1)
        pre = preHead
        while l1 and l2:
            if l1.val<=l2.val:
                pre.next = l1
                l1=l1.next
            else:
                pre.next = l2
                l2=l2.next
            pre = pre.next
        if l1 is not None:
            pre.next =l1
        else:
            pre.next =l2
        return preHead.next
  • 思想

  • 备注

https://www.nowcoder.com/practice/a479a3f0c4554867b35356e0d57cf03d?tpId=117&tqId=37735&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/

13.两数之和(0317)

  • 题目
    给出一个整数数组,请在数组中找出两个加起来等于目标值的数,
    你给出的函数twoSum 需要返回这两个数字的下标(index1,index2),需要满足 index1 小于index2.。注意:下标是从1开始的
    假设给出的数组中只存在唯一解
    例如:
    给出的数组为 {20, 70, 110, 150},目标值为90
    输出 index1=1, index2=2
示例1
输入
[3,2,4],6
返回值
[2,3]
  • 代码
class Solution:
    def twoSum(self , numbers , target ):
        # write code here
        dic = {}
        for i,num in enumerate(numbers):
            if target-num in dic:
                return [dic[target-num]+1,i+1]
            dic[num]=i
        return []
  • 思想
    定义一个哈希表字典,把数组中的遍历索引和元素,如果目标值减去某元素存在于字典中,则返回字典中该元素的值,值为它在原数组中的索引,和当前遍历到的索引。如果目标值减去某元素不存在于字典中,则把该元素和它的索引值存入字典,字典的键为元素,值为该元素在数组中的索引。

  • 备注

  1. enumerate() 函数
    用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
    语法
    以下是 enumerate() 方法的语法:
    enumerate(sequence, [start=0])
    参数
    sequence – 一个序列、迭代器或其他支持迭代对象。
    start – 下标起始位置。
    返回值
    返回 enumerate(枚举) 对象。
>>>seq = ['one', 'two', 'three']
>>> for i, element in enumerate(seq):
...     print i, element
... 
0 one
1 two
2 three

https://leetcode-cn.com/problems/two-sum/
https://www.nowcoder.com/practice/20ef0972485e41019e39543e8e895b7f?tpId=117&tqId=37756&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

14.跳台阶(0317)-同斐波那契数列

  • 题目
    一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
  • 代码
# -*- coding:utf-8 -*-
class Solution:
    def jumpFloor(self, number):
        # write code here
        j_2=1 #前两步
        j_1=2 #前一步
        j=0 #当前步骤
        if number==1:
            return 1
        if number==2:
            return 2
        for i in range(3,number+1):
            j=j_1+j_2
            j_2=j_1
            j_1=j
        return j
  • 思想
    对于第n个台阶来说,只能从n-1或者n-2的台阶跳上来,所以F(n) = F(n-1) + F(n-2),循环迭代
  • 备注

https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=117&tqId=37764&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/solution/qing-wa-tiao-tai-jie-xiang-jie-by-hh123-p842q/

15.子数组的最大累加和问题(0317)

  • 题目
    给定一个数组arr,返回子数组的最大累加和
    例如,arr = [1, -2, 3, 5, -2, 6, -1],所有子数组中,[3, 5, -2, 6]可以累加出最大的和12,所以返回12.题目保证没有全为负数的数据
    [要求]
    时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)
示例1
输入
[1, -2, 3, 5, -2, 6, -1]
12
  • 代码
class Solution:
    def maxsumofSubarray(self , arr ):
        # write code here
        max=0
        sum=0
        for i in arr:
            if sum>=0:
                sum=sum+i
            else:
                sum=i
            if sum>max:
                max=sum
        return max
  • 思想
    贪心法:
    首先定义当前和为0,最大和为0,遍历数组,当前和大于0的时候,累加当前数组元素,否则放弃之前累加和,从当前元素开始重新累加和。然后把当前累加和与历史最大和进行比较,保留较大的那个作为最大和。以此类推。
  • 备注

https://www.nowcoder.com/practice/554aa508dd5d4fefbf0f86e5fe953abd?tpId=117&tqId=37797&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/maximum-subarray/solution/zui-da-zi-xu-he-cshi-xian-si-chong-jie-fa-bao-li-f/

链表中的节点每k个一组翻转(待解决)

  • 题目
    将给出的链表中的节点每\ k k 个一组翻转,返回翻转后的链表
    如果链表中的节点数不是\ k k 的倍数,将最后剩下的节点保持原样
    你不能更改节点中的值,只能更改节点本身。
    要求空间复杂度 \ O(1) O(1)
    例如:
    给定的链表是1\to2\to3\to4\to51→2→3→4→5
    对于 \ k = 2 k=2, 你应该返回 2\to 1\to 4\to 3\to 52→1→4→3→5
    对于 \ k = 3 k=3, 你应该返回 3\to2 \to1 \to 4\to 53→2→1→4→5

  • 代码

  • 思想

  • 备注

https://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e?tpId=117&tqId=37746&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

16.合并两个有序的数组(0318)

  • 题目
    给出两个有序的整数数组 和 ,请将数组 合并到数组 中,变成一个有序的数组
    注意:
    可以假设 数组有足够的空间存放 数组的元素, 和 中初始的元素数目分别为 和
    方法一:双指针法
  • 代码
class Solution(object):
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """
        nums1_copy = nums1[:m] 
        nums1[:] = []
        p1=0
        p2=0
        while p1<m and p2<n:
            if nums1_copy[p1]<nums2[p2]:
                nums1.append(nums1_copy[p1])
                p1+=1
            else:
                nums1.append(nums2[p2])
                p2+=1
        if p1<m:
            nums1[p1+p2:]=nums1_copy[p1:]
        if p2<n:
            nums1[p1+p2:]=nums2[p2:]
        return nums1
  • 思想
    一般而言,对于有序数组可以通过 双指针法 达到O(n+m)的时间复杂度。
    最直接的算法实现是将指针p1 置为 nums1的开头, p2为 nums2的开头,在每一步将最小值放入输出数组中。
    由于 nums1 是用于输出的数组,需要将nums1中的前m个元素放在其他地方,也就需要 O(m)O(m) 的空间复杂度。
    方法二:逆向双指针法
  • 代码
class Solution(object):
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """
        p1 = m-1
        p2 = n-1
        tail = m+n-1
        while p1>=0 and p2>=0:
            if nums1[p1]>nums2[p2]:
                nums1[tail]=nums1[p1]
                p1-=1
            else:
                nums1[tail]=nums2[p2]
                p2-=1
            tail-=1
        nums1[:p2+1]=nums2[:p2+1]
        return nums1
  • 思想
    nums1的长度一定可以包含nums2的长度,应该是m+n的长。然后就可以从后往前双指针计算,一定不会出现还没计算到就把nums1的元素覆盖的情况。最后的nums1[:p2+1]=nums2[:p2+1]意思是,如果p1<0了,就把nums2前面剩下的放到nums1前面。为什么没有把nums1剩下的放到前面的操作,因为本来就在nums1中操作,它里面的元素一直在里面。
  • 备注
    https://leetcode-cn.com/problems/merge-sorted-array/solution/he-bing-liang-ge-you-xu-shu-zu-by-leetcode/
    https://www.nowcoder.com/practice/89865d4375634fc484f3a24b7fe65665?tpId=117&tqId=37727&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

17.链表中环的入口节点(0318)

  • 题目
    对于一个给定的链表,返回环的入口节点,如果没有环,返回null
    拓展:
    你能给出不利用额外空间的解法么?

  • 代码

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

#
# 
# @param head ListNode类 
# @return ListNode类
#
class Solution:
    def detectCycle(self , head ):
        # write code here
        if not head or not head.next:
            return None
        slow = head
        fast = head
        while fast and fast.next is not None:
            slow = slow.next
            fast = fast.next.next
            if fast == slow:
                slow = head
                while slow!=fast:
                    slow=slow.next
                    fast=fast.next
                return slow
        return None
  • 思想
    在这里插入图片描述

  • 备注

https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/142-huan-xing-lian-biao-iishuang-zhi-zhe-k8ju/ https://www.nowcoder.com/practice/6e630519bf86480296d0f1c868d425ad?tpId=117&tqId=37713&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

18.括号序列(0319)

  • 题目
    给出一个仅包含字符’(‘,’)‘,’{‘,’}‘,’[‘和’]',的字符串,判断给出的字符串是否是合法的括号序列
    括号必须以正确的顺序关闭,"()“和”()[]{}“都是合法的括号序列,但”(]“和”([)]"不合法。
示例1
输入
"["
返回值
false
  • 代码
#
# 
# @param s string字符串 
# @return bool布尔型
#
class Solution:
    def isValid(self , s ):
        # write code here
        d = {"(": ")", "[":"]", "{":"}"}
        stack=[]
        for i in s:
            if i in d:
                stack.append(i)
            else:
                if not stack or i!=d[stack.pop()]:
                    return False
        if not stack:
            return True
        else:
            return False
  • 思想
    栈的思想
    首先定义一个字典,键值分别为左边括号和右边括号。定义一个栈用来进出括号。遍历字符串,如果遇到字典中键的左边括号,则将其入栈。如果不是,就说明遇到了右边括号,则查看栈,如果栈为空,说明无法匹配,返回False,如果栈不为空,则将栈顶元素弹出,弹出的是某种左边括号,需要通过键值对来从字典中找到右边括号,然后与遍历到的元素对比,如果一致,则继续循环。如果不一致,则返回False。遍历结束后,如果栈中没有元素了,说明括号得以匹配,返回True,否则返回False。
  • 备注

https://www.nowcoder.com/practice/37548e94a270412c8b9fb85643c8ccc2?tpId=117&tqId=37749&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

19.找到字符串的最长无重复字符子串(0319不是特别明白-0426滑动窗口)

  • 题目
    给定一个数组arr,返回arr的最长无的重复子串的长度(无重复指的是所有数字都不相同)。
示例1
输入
[2,3,4,5]
返回值
4

新学会的方法—滑动窗口----理解起来比较简单

  • 代码
class Solution:
    def maxLength(self , arr ):
        # write code here
        list=[]
        max=0
        for i in arr:
            while i in list:
                list.remove(list[0])
            list.append(i)
            if len(list)>max:
                max=len(list)
        return max
  • 思想
    其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以要移动这个队列,如何移动?只要把队列的左边的元素移出就行了,直到满足题目要求,一直维持这样的队列,找出队列出现最长的长度时候,求出解。

  • 代码

#
# 
# @param arr int整型一维数组 the array
# @return int整型
#
class Solution:
    def maxLength(self , arr ):
        # write code here
        dic = {}
        res = 0
        i = -1
        for j in range(len(arr)):
            if arr[j] in dic:
                i = max(dic[arr[j]], i)
            dic[arr[j]] = j
            res = max(res, j-i)
        return res
  • 思想
    据说是动态规划
    在这里插入图片描述

  • 备注

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-leetc-2/

https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/mian-shi-ti-48-zui-chang-bu-han-zhong-fu-zi-fu-d-9/

20.最长公共子串(0322没学会)

  • 题目
    给定两个字符串str1和str2,输出两个字符串的最长公共子串
    题目保证str1和str2的最长公共子串存在且唯一。
示例1
输入
"1AB2345CD","12345EF"
返回值
"2345"
  • 代码
class Solution:
    def findLength(self, A: List[int], B: List[int]) -> int:
        n, m = len(A), len(B)
        dp = [[0] * (m + 1) for _ in range(n + 1)]
        #生成m+1列,n+1行元素为0的数组
        ans = 0
        for i in range(n - 1, -1, -1):
            for j in range(m - 1, -1, -1):
                dp[i][j] = dp[i + 1][j + 1] + 1 if A[i] == B[j] else 0
                ans = max(ans, dp[i][j])
        return ans
  • 思想
    在这里插入图片描述
  • 备注

https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/solution/zui-chang-zhong-fu-zi-shu-zu-by-leetcode-solution/

https://www.nowcoder.com/practice/f33f5adc55f444baa0e0ca87ad8a6aac?tpId=117&tqId=37799&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

最长公共子串,两个序列的连续公共子串—输出子串(0427动态规划)

  • 题目
    给定两个字符串str1和str2,输出两个字符串的最长公共子串
    题目保证str1和str2的最长公共子串存在且唯一。
输入
"1AB2345CD","12345EF"
返回值
"2345"
  • 代码
class Solution:
    def LCS(self , str1 , str2 ):
        m = len(str1)
        n = len(str2)
        ans=0
        end =0
        dp = [[0 for _ in range(n+1)]for _ in range(m+1)]
        for i in range(1,m+1):
            for j in range(1,n+1):
                if str1[i-1]==str2[j-1]:
                    dp[i][j]=dp[i-1][j-1]+1
                if dp[i][j]>ans:
                    ans=dp[i][j]
                    end = i
        return str1[end-ans:end]

https://www.nowcoder.com/practice/f33f5adc55f444baa0e0ca87ad8a6aac?tpId=117&tqId=37799&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey

最长重复子数组(与上题一样,只是返回的是长度)

  • 题目
    给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。
示例:
输入:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
输出:3
解释:
长度最长的公共子数组是 [3, 2, 1]
  • 代码
class Solution(object):
    def findLength(self, nums1, nums2):
        m = len(nums1)
        n = len(nums2)
        ans=0
        dp = [[0 for _ in range(n+1)]for _ in range(m+1)]
        for i in range(1,m+1):
            for j in range(1,n+1):
                if nums1[i-1]==nums2[j-1]:
                    dp[i][j]=dp[i-1][j-1]+1
                    ans=max(dp[i][j],ans)
        return ans

https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/
https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/solution/zhe-yao-jie-shi-ken-ding-jiu-dong-liao-by-hyj8/
https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/solution/ni-de-yi-fu-wo-ba-liao-zui-chang-gong-gong-zi-xu-l/

问题

  • 题目

  • 代码

class Solution:
    def solve(self , str ):
        # write code here
        ans = []
        j = len(str) - 1
        for i, x in enumerate(str):
            if x.isalpha():
                while not str[j].isalpha():
                    j -= 1
                ans.append(str[j])
                j -= 1
            else:
                ans.append(x)
        
        return "".join(ans)
  • 思想

  • 备注

21.进制转换(0323)

  • 题目
    给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数
示例
输入
7,2
返回值
"111"
  • 代码
class Solution:
    def solve(self , M , N ):
        # write code here
        base_map ="0123456789ABCDEF"
        baseN=[]
        flag = 0
        if M<0:
            flag = 1
            M = -M
        while M >0:
            fig = M%N
            baseN.append(base_map[fig])
            M = M // N
        if flag:
            baseN.append("-")
        baseN.reverse()
        return "".join(baseN)
  • 思想
    如果给定数字为负数,标记flag为1,然后转换为正数,后面计算完了后再加上负号。定义一个base_map作为进制转换“0123456789ABCDEF”,当数字大于0,数字除以进制取余,余数对应的的下标来找到base_map对应的元素放入事先定义好的列表中。然后将该数字除以进制数,向下取整。(3.5–>3)。循环直到数字为0。然后要把列表翻转。原因是使用“短除法“的原理。然后转换成字符串返回即可。
  • 备注
    % 取模 - 返回除法的余数 b % a 输出结果 0
    // 取整除 - 返回商的整数部分(向下取整)

>>> 9//2
4
>>> -9//2
-5

https://www.nowcoder.com/practice/2cc32b88fff94d7e8fd458b8c7b25ec1?tpId=196&tqId=37170&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/base-7/

22.计数质数(0324)

  • 题目
    统计所有小于非负整数 n 的质数的数量。
    示例:
    输入:n = 10
    输出:4
    解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。

  • 代码

class Solution(object):
    def countPrimes(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n < 2:
            return 0
        is_prime = [1]*n
        count = 0
        for i in range(2,n):
            if is_prime[i]:
                count+=1
                for j in range(i*i, n ,i):
                    is_prime[j]=0
        return count
  • 思想
  1. 质数(Prime number),又称素数,指在大于 1 的自然数中,除了 1 和该数自身外,无法被其他自然数整除的数。
  2. 最小的质数是2
  3. 算法的思想是“埃氏筛”,把是质数的数的倍数的数都排除掉,剩下的就是质数。(埃氏筛的原理:从 2 开始,将每个质数的倍数都标记为合数。同样的,标记到根号n停止。假设一个数 i为质数时,那么此时大于 i且是 i 的倍数的数一定不是质数,例如 2i,3i…。那么我们将这些不是质数的数进行标记。
    这里需要注意,标记应该从 i * i开始,而不是 2 * i开始。因为对于每个数 i来说,枚举是从小到大的,此时前面数字的倍数都已经进行了标记。对于 i而言,2∗i 也肯定会被在枚举数字 2 时进行标记,[2, i)区间的数同理。)
  4. range(start, stop[, step])
    参数说明:
    start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
    stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
    step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)
>>> range(0, 30, 5)  # 步长为 5
[0, 5, 10, 15, 20, 25]
  • 备注

https://leetcode-cn.com/problems/count-primes/solution/ji-shu-zhi-shu-ai-shi-shai-by-yiluolion/

23.验证IP地址(0324)

  • 题目
    编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。
    如果是有效的 IPv4 地址,返回 “IPv4” ;
    如果是有效的 IPv6 地址,返回 “IPv6” ;
    如果不是上述类型的 IP 地址,返回 “Neither” 。

  • 代码

class Solution:
    def validIPAddress(self, IP: str) -> str:
        if IP=="":
            return "Neither"
        if '.' in IP:
            # val ipv4
            ips = IP.split('.')
            if len(ips) != 4:
                return "Neither"
            for i in ips:
                try:
                    num = int(i)
                    if len(i) > 1 and i[0] == '0':
                        return 'Neither'
                    if num >= 0 and num <= 255:
                        continue
                    else:
                        return 'Neither'
                except ValueError:
                    return 'Neither'
            return "IPv4"
        elif ':' in IP:
            ips = IP.split(':')
            if len(ips) != 8:
                return "Neither"
            # val ipv6
            for a in IP.split(':'):
                if len(a) == 0 or len(a) > 4:
                    return "Neither"
                for aa in a:
                    if aa not in '0123456789abcdefABCDEF':
                        return "Neither" 
            return "IPv6"
  • 思想

IPv4:

  1. 段地址数只能为4;
  2. 以0开头时只允许长度为1;
  3. 段地址必须是可以进行int()的字符串;int()之后必须在[0,255]区间;

IPv6

  1. 段地址数只能为8;
  2. 段地址只允许长度为[1,4]区间;
  3. 段地址每个字符必须是合法的16进制字符,例如G不合法;
  • 备注
    IPv4 地址由十进制数和点来表示,每个地址包含 4 个十进制数,其范围为 0 - 255, 用(“.”)分割。比如,172.16.254.1;
    同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。
    IPv6 地址由 8 组 16 进制的数字来表示,每组表示 16 比特。这些组数字通过 (“:”)分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。
    然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (:: ) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。
    同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。

https://leetcode-cn.com/problems/validate-ip-address/solution/yong-shi-ji-bai-96jian-dan-si-lu-by-darkwhite/
https://www.nowcoder.com/practice/55fb3c68d08d46119f76ae2df7566880?tpId=196&tqId=37171&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey

24.回文数字(0325)

  • 题目
    在不使用额外的内存空间的条件下判断一个整数是否是回文数字
输入
121
返回值
true
  • 代码
class Solution:
    def isPalindrome(self , x ):
        # write code here
        revertedNumber = 0
        if (x%10==0 and x!=0) or x<0:
            return False
        while  x > revertedNumber :
            revertedNumber = revertedNumber*10 + x%10
            x=x//10
        return revertedNumber==x or x==revertedNumber//10
  • 思想:取出后半段数字进行翻转
  • 回文数:将数字进行对折后看能否一一对应。
  • 负数不会是回文数,最后一位为0的数也不是回文,但是0是回文数。
  • 这里需要注意的一个点就是由于回文数的位数可奇可偶,所以当它的长度是偶数时,它对折过来应该是相等的;当它的长度是奇数时,那么它对折过来后,有一个的长度需要去掉一位数(除以 10 并取整)。
  • 具体做法如下:
  1. 每次进行取余操作 ( %10),取出最低的数字:y = x % 10
  2. 将最低的数字加到取出数的末尾:revertNum = revertNum * 10 + y
  3. 每取一个最低位数字,x 都要自除以 10
  4. 判断 x 是不是小于 revertNum ,当它小于的时候,说明数字已经对半或者过半了
  5. 最后,判断奇偶数情况:如果是偶数的话,revertNum 和 x 相等;如果是奇数的话,最中间的数字就在revertNum 的最低位上,将它除以 10 以后应该和 x 相等。
  • 备注

https://leetcode-cn.com/problems/palindrome-number/solution/dong-hua-hui-wen-shu-de-san-chong-jie-fa-fa-jie-ch/
https://www.nowcoder.com/practice/35b8166c135448c5a5ba2cff8d430c32?tpId=196&tqId=37087&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey

25.回文字符串(0325)

  • 题目
    给定一个字符串,请编写一个函数判断该字符串是否回文。如果回文请返回true,否则返回false。
示例
输入
"absba"
返回值
true
  • 代码
class Solution:
    def judge(self , str ):
        # write code here
        i = 0
        j = len(str)-1
        while i<j:
            if str[i]!=str[j]:
                return False
            i+=1
            j-=1
        return True
  • 思想:双指针
    一前一后双指针,前后元素一一对比,如果一样就循环到两个指针汇合,如果不一样就返回false

  • 备注

https://www.nowcoder.com/practice/e297fdd8e9f543059b0b5f05f3a7f3b2?tpId=196&tqId=37186&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey

26.验证回文串"A man, a plan, a canal: Panama"(0325)

  • 题目
    给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
    说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
示例 2:
输入: "race a car"
输出: false
  • 代码
    方法一:需要额外的存储空间
class Solution(object):
    def isPalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        list =[]
        for i in s:
            if i.isalnum():
                list.append(i.lower())
        list ="".join(list)
        #sgood = "".join(ch.lower() for ch in s if ch.isalnum())
        i = 0
        j = len(list)-1
        while i < j :
            if list[i]!=list[j]:
                return False
            i+=1
            j-=1
        return True

方法二:不需要额外的存储空间

class Solution(object):
    def isPalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        # list =[]
        # for i in s:
        #     if i.isalnum():
        #         list.append(i.lower())
        # list ="".join(list)
        # #sgood = "".join(ch.lower() for ch in s if ch.isalnum())
        i = 0
        j = len(s)-1
        while i < j :
            while i<j and not s[i].isalnum():
                i+=1
            while i<j and not s[j].isalnum():
                j-=1
            if i<j and s[i].lower()!=s[j].lower():
                return False
            i+=1
            j-=1
        return True
  • 思想
    两个方法的思想基本上是一样的,两个指针,一个在头,一个在尾,先判断此刻的元素是否是数字字母,如果不是,就不要比较它。如果是就比较是否一致,不一致就返回fasle,循环。
  • 备注
  1. Python isalnum() 方法检测字符串是否由字母和数字组成。
    isalnum()方法语法:str.isalnum()
    返回值:如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False
str = "this is string example....wow!!!";
print str.isalnum();
False

https://leetcode-cn.com/problems/valid-palindrome/solution/yan-zheng-hui-wen-chuan-by-leetcode-solution/

27.最接近的三数之和(0326)

  • 题目
    给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2)
  • 代码
class Solution(object):
    def threeSumClosest(self, nums, target):
        nums.sort()
        n = len(nums)
        best = nums[0]+nums[1]+nums[2]
      
        # 枚举 a
        for i in range(n):
            # 保证和上一次枚举的元素不相等
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            # 使用双指针枚举 b 和 c
            j, k = i + 1, n - 1
            while j < k:
                s = nums[i] + nums[j] + nums[k]
                # 如果和为 target 直接返回答案
                if s == target:
                    return target
                if s > target:
                    # 如果和大于 target,移动 c 对应的指针
                    k0 = k - 1
                    # 移动到下一个不相等的元素
                    while j < k0 and nums[k0] == nums[k]:
                        k0 -= 1
                    k = k0
                else:
                    # 如果和小于 target,移动 b 对应的指针
                    j0 = j + 1
                    # 移动到下一个不相等的元素
                    while j0 < k and nums[j0] == nums[j]:
                        j0 += 1
                    j = j0
                # 根据差值的绝对值来更新答案
                if abs(s - target) < abs(best - target):
                    best = s
        return best
  • 思想:排序 + 双指针
    题目要求找到与目标值target 最接近的三元组,这里的「最接近」即为差值的绝对值最小。
    首先考虑枚举第一个元素 a,对于剩下的两个元素 b 和 c,希望它们的和最接近target−a。对于 b 和 c,对整个数组进行升序排序,这样一来:
    假设数组的长度为 n,我们先枚举 a,它在数组中的位置为 i;
    为了防止重复枚举,我们在位置 [i+1, n)的范围内枚举 b 和 c。
    借助双指针,一个指针在i+1的位置,一个在n的位置,只要前一个指针比后一个指针小的情况下,如果当前三个数的和小于target,则把左边的指针向右移动一位,这样三个数的和会增大一点,以此类推。大于target的情况就是右边指针向前移动。
    优化:
    本题也有一些可以减少运行时间(但不会减少时间复杂度)的小优化。当我们枚举到恰好等于target 的 a+b+c时,可以直接返回target 作为答案,因为不会有再比这个更接近的值了。
    当我们枚举 a, b, c中任意元素并移动指针时,可以直接将其移动到下一个与这次枚举到的不相同的元素,减少枚举的次数。
  1. continue的用法
    continue 语句用来告诉Python跳过当前循环的剩余语句,然后继续进行下一轮循环。
    continue语句用在while和for循环中。
for letter in 'Python': 
   if letter == 'h':
      continue  #当字母为h时,直接跳出本次循环,后面的代码不再执行
   print'当前字母 :', letter)
输出结果:
当前字母 : P
当前字母 : y
当前字母 : t
当前字母 : o
当前字母 : n
  • 备注

https://leetcode-cn.com/problems/3sum-closest/

28.计算字符串中子串出现的次数(0326)

  • 题目
    输入:
    输入以空格相隔的两个字符串(字符数不大于20个),敲回车
    输出:
    统计第一个字符串中 第二个字符串 出现的次数
样例输入
Goodoo o
样例输出
4
  • 代码
def zifuchuan(str):
    target = str.split(" ")[0]
    s = str.split(" ")[1]
    count = 0
    for i in range(len(s)):
            if s[i:i+len(target)]==target:
                count+=1
    return count
  • 思想
    首先把两个字符串分隔开。然后从长串从第0个元素开始遍历,如果长串切片[i:i+len(target)从第i个元素到第i+目标的长度结束,其实就是查找长串中目标串长度的字符串是不是与目标相同。
  • 备注

添加最少的字符让字符串变为回文字符串(未解决)

  • 题目
    给定一个字符串str,如果可以在str的任意位置添加字符,请返回在添加字符最少的情况下,让str整体都是回文字符串的一种结果。
输入描述:
输入包含一行字符串,代表str
输出描述:
输出一行,代表返回的字符串。
示例
输入
AB
输出
ABA
  • 代码

  • 思想

  • 备注

https://leetcode-cn.com/problems/minimum-insertion-steps-to-make-a-string-palindrome/solution/rang-zi-fu-chuan-cheng-wei-hui-wen-chuan-de-zui–2/

https://www.nowcoder.com/practice/a5849b7e3bc940ff8c97b47d3f76199b?tpId=101&tqId=33192&tPage=1&rp=1&ru=%2Fta%2Fprogrammer-code-interview-guide&qru=%2Fta%2Fprogrammer-code-interview-guide%2Fquestion-ranking&tab=answerKey

29.删除有序数组中的重复项(0326)

  • 题目
    给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
    不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

  • 代码

class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        slow = fast = 0
        while fast<(len(nums)):
            if nums[slow]==nums[fast]:
                fast+=1
            else:
                slow+=1
                nums[slow]=nums[fast]
        return slow+1
         # for fast in range(len(nums)):
        #     if nums[slow]!=nums[fast]:
        #         slow+=1
        #         nums[slow]=nums[fast]
        # return slow+1

  • 思想:双指针
    设置两个指针一个在前fast一个在后slow,开始时都在数组起点。fast根据数组长度遍历,如果fast的元素与slow的元素一致,则忽略,fast向下一个取,如果不一致,则把slow指针向前移一步,然后把fast的值赋给slow。最后,数组中的slow+1个元素是无重复的,返回即可

  • 备注

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

30.左旋转字符串(0329)

  • 题目
    字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
    输入: s = “abcdefg”, k = 2
    输出: “cdefgab”
  • 代码
方法一:用list
class Solution:
    def LeftRotateString(self, s, n):
        # write code here
        if s=="":
            return ""
        res = []
        for i in range(n,len(s)):
            res.append(s[i])
        for i in range(0,n):
            res.append(s[i])
        return "".join(res)

方法二:字符串拼接
class Solution:
    def LeftRotateString(self, s, n):
        # write code here
        if s=="":
            return ""
        res = ""
        for i in range(n,len(s)):
            res = res+s[i]
        for i in range(0,n):
            res = res+s[i]
        return res

方法三:字符串切片
class Solution:
    def LeftRotateString(self, s, n):
        # write code here
        return s[n:]+s[:n]
  • 思想
    思想都是一样的,先把字符串后n位放入,然后放前n位
  • 备注

https://www.nowcoder.com/questionTerminal/12d959b108cb42b1ab72cef4d36af5ec

https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/solution/mian-shi-ti-58-ii-zuo-xuan-zhuan-zi-fu-chuan-qie-p/

31.二分查找递归与非递归实现

  • 题目

https://leetcode-cn.com/problems/binary-search/solution/er-fen-cha-zhao-xiang-jie-by-labuladong/

  • 代码
非递归方法:
class Solution(object):
    def search(self, nums, target):
        left = 0 
        right = len(nums)-1
        while left<=right:
            mid = (left+right)//2  # mid = left + (right - left)//2
            if nums[mid]==target:
                return mid
            elif nums[mid]<target:
                left+=1
            elif nums[mid]>target:
                right-=1
        return -1
递归方法:好像不太对
class Solution(object):
    def search(self, nums, target):
        mid = len(nums)//2
        if nums[mid]==target:
            return mid
        elif nums[mid]>target:
            return search(nums[mid+1:], target)
        elif nums[mid]<target:
            return search(nums[:mid], target)
        return


  • 思想

  • 备注

32.Excel表列序号(0331)

  • 题目
    给定一个Excel表格中的列名称,返回其相应的列序号。
    例如,
    A -> 1
    B -> 2
    C -> 3

    Z -> 26
    AA -> 27
    AB -> 28
示例 1:
输入: "A"
输出: 1
示例 2:
输入: "AB"
输出: 28
  • 代码
class Solution(object):
    def titleToNumber(self, columnTitle):
        """
        :type columnTitle: str
        :rtype: int
        """
        ans = 0
        for i in range(len(columnTitle)):
            num = ord(columnTitle[i])-ord('A')+1
            ans = ans*26+num
        return ans
  • 思想
    二十六进制
  • 备注
  • ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。
    语法::ord©
    参数:c – 字符。
    返回值:返回值是对应的十进制整数。

33.只买卖一次股票的最大利润(0401)

  • 题目
    假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
示例:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
  • 代码
class Solution:
    def maxProfit(self , prices ):
        # write code here
        maxProfit = 0
        minprice = prices[0]
        for i in prices:
            maxProfit = max(i-minprice , maxProfit)
            minprice = min(minprice, i)
        return maxProfit
  • 思想
    首先定义一个最大利润为0,最低价格为第一天的价格。然后遍历每天的价格,首先计算当前的最大利润,肯定是当前价格减去之前某天出现的最低价格,比较取最大值。然后再将当天价格与历史最低价格比较,留下较小的。一定要先计算最大利润,因为只能与之前的最低价格计算,佣金天的价格计算没有意义。
  • 备注

https://www.nowcoder.com/practice/64b4262d4e6d4f6181cd45446a5821ec?tpId=196&tqId=37051&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/

34.无限次买卖股票的最大利润(0401)

  • 题目
    假定你知道某只股票每一天价格的变动。
    你最多可以同时持有一只股票。但你可以无限次的交易(买进和卖出均无手续费)。
    请设计一个函数,计算你所能获得的最大收益。
示例1
输入
[5,4,3,2,1]
返回值
0
说明
由于每天股票都在跌,因此不进行任何交易最优。最大收益为0
  • 代码
class Solution:
    def maxProfit(self , prices ):
        # write code here
        ans = 0
        for i in range(1, len(prices)):
            if prices[i] > prices[i-1]:
                ans = ans + prices[i] - prices[i-1]
        return ans
  • 思想
    只要后一天的价格比前一天的高,就有收益,就累加起来。贪心算法。
  • 备注

https://www.nowcoder.com/practice/9e5e3c2603064829b0a0bbfca10594e9?tpId=196&tqId=37180&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/solution/best-time-to-buy-and-sell-stock-ii-zhuan-hua-fa-ji/

35.删除排序链表中的重复元素(0401)

  • 题目
    存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 。
    返回同样按升序排列的结果链表。
    在这里插入图片描述

  • 代码

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

#
# 
# @param head ListNode类 
# @return ListNode类
#
class Solution:
    def deleteDuplicates(self , head ):
        # write code here
        if not head:
            return head
        cur = head
        while cur.next:
            if cur.val==cur.next.val:
                cur.next=cur.next.next
            else:
                cur = cur.next
        return head
  • 思想
    一次遍历
    由于给定的链表是排好序的,因此重复的元素在链表中出现的位置是连续的,因此我们只需要对链表进行一次遍历,就可以删除重复的元素。
    我们从指针 cur 指向链表的头节点,随后开始对链表进行遍历。如果当前 cur 与cur.next 对应的元素相同,那么我们就将cur.next 从链表中移除;否则说明链表中已经不存在其它与cur 对应的元素相同的节点,因此可以将 cur 指向 cur.next。当遍历完整个链表之后,返回链表的头节点即可。
    细节
    当我们遍历到链表的最后一个节点时,cur.next 为空节点,如果不加以判断,访问cur.next 对应的元素会产生运行错误。因此我们只需要遍历到链表的最后一个节点,而不需要遍历完整个链表。
  • 备注

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/

二叉树前序遍历

  • 题目

  • 代码

  • 思想

  • 备注

36.数组中未出现的最小正整数(0407)

  • 题目
    给定一个无序数组arr,找到数组中未出现的最小正整数
    例如arr = [-1, 2, 3, 4]。返回1
    arr = [1, 2, 3, 4]。返回5
    [要求]
    时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)
  • 代码
class Solution:
    def minNumberdisappered(self , arr ):
        # write code here
        for i in range(len(arr)):
            while 1<=arr[i]<=len(arr) and arr[arr[i]-1]!=arr[i]:
                arr[arr[i]-1],arr[i]=arr[i],arr[arr[i]-1]
        for i in range(len(arr)):
            if arr[i]!= i+1:
                return i+1
        return len(arr)+1
  • 思想
    要把数组中属于1-n的数字挑出来,然后与下标对应放进去,再查找谁与下标不对应,就是没有的最小的那个正整数,如果都对应了,最小的就是n+1。遍历数组,如果该数字arr[i]在1-n之间,并且与arr[arr[i]-1]不同,则将其互换。(为啥是arr[i]-1,因为数组下标从0开始,但是要找正整数,所以所有的数都往前移一个下标)遍历过后,再遍历一边数组,找到arr[i]不等于i+1的,就返回i+1,如果没有,就说明都对应上了,返回n+1
  • 备注

https://www.nowcoder.com/practice/8cc4f31432724b1f88201f7b721aa391?tpId=196&tqId=37133&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/first-missing-positive/solution/que-shi-de-di-yi-ge-zheng-shu-by-leetcode-solution/

37.调整数组顺序使奇数位于偶数前面(0408)

  • 题目
    输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
    示例:
    输入:nums = [1,2,3,4]
    输出:[1,3,2,4]
    注:[3,1,2,4] 也是正确的答案之一。
  • 代码
class Solution(object):
    def exchange(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        i = 0
        j = len(nums)-1
        while i < j:
            while i < j and nums[i]%2==1:
                i+=1
            while i < j and nums[j]%2==0:
                j-=1
            nums[i],nums[j]=nums[j],nums[i]
        return nums
  • 思想
    两个指针,前一个找到不是奇数的,后一个找到不是偶数的,互换。
    如果想要奇数偶数相对位置不变,可以弄两个列表,奇数放一个,偶数放一个,然后相加即可。

  • 备注

https://www.nowcoder.com/practice/ef1f53ef31ca408cada5093c8780f44b?tpId=196&tqId=37110&rp=1&ru=%2Factivity%2Foj&qru=%2Fta%2Fjob-code-total%2Fquestion-ranking&tab=answerKey
https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/

38.打家劫舍I(0409)

  • 题目
    你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
    给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4
  • 代码
class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        if len(nums)==1:
            return nums[0]
        s1 = nums[0]
        s2 = max(nums[0],nums[1])
        for i in range(2,len(nums)):
            s1,s2 = s2, max(s1+nums[i],s2)
        return s2
  • 思想:动态规划
    在这里插入图片描述
    因为相邻的房子不能偷,所以,每到一间房间偷东西的最大利益有两种情况:
    (1)偷当前这家的利益+偷前前家方案的最大利益
    (2)不偷这家,利益就是偷前一家的最大利益
    就出现了递推公式,见图

  • 备注

https://leetcode-cn.com/problems/house-robber/solution/da-jia-jie-she-by-leetcode-solution/

39.打家劫舍 II(0409)

  • 题目
    你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
    给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,能够偷窃到的最高金额。
示例:
输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2, 因为他们是相邻的。
  • 代码
class Solution:
    def rob(self, nums: List[int]) -> int:
        def a (nums):
            if nums==[]:
                return 0
            elif len(nums)==1:
                return nums[0]
            s1 = nums[0]
            s2 = max(nums[1], nums[0])
            for i in range(2,len(nums)):
                s1 , s2 =s2 ,max(s2,s1+nums[i])
            return s2
        if nums==[]:
            return 0
        elif len(nums)==1:
            return nums[0]
        else:
            return max(a(nums[1:]),a(nums[:-1]))
  • 思想
    方法同第一种打家劫舍,看做不能偷第一家和不能偷最后一家的两种情况就好了。
  • 备注

https://leetcode-cn.com/problems/house-robber-ii/solution/213-da-jia-jie-she-iidong-tai-gui-hua-jie-gou-hua-/

40. 相交链表

  • 题目
    在这里插入图片描述

  • 代码

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

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        A = headA
        B = headB
        while A != B:
            if A:
                A=A.next
            else:
                A=headB
            if B:
                B=B.next
            else:
                B=headA
        return A
  • 思想
    在这里插入图片描述

  • 备注

https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

41. 比较版本号

  • 题目
    给你两个版本号 version1 和 version2 ,请你比较它们。
    版本号由一个或多个修订号组成,各修订号由一个 ‘.’ 连接。每个修订号由 多位数字 组成,可能包含 前导零 。每个版本号至少包含一个字符。修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0 ,下一个修订号下标为 1 ,以此类推。例如,2.5.33 和 0.1 都是有效的版本号。
    比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较 忽略任何前导零后的整数值 。也就是说,修订号 1 和修订号 001 相等 。如果版本号没有指定某个下标处的修订号,则该修订号视为 0 。例如,版本 1.0 小于版本 1.1 ,因为它们下标为 0 的修订号相同,而下标为 1 的修订号分别为 0 和 1 ,0 < 1 。
    返回规则如下:
    如果 version1 > version2 返回 1,
    如果 version1 < version2 返回 -1,
    除此之外返回 0。
    示例 1:
    输入:version1 = “1.01”, version2 = “1.001”
    输出:0
    解释:忽略前导零,“01” 和 “001” 都表示相同的整数 “1”

  • 代码

class Solution:
    def compareVersion(self, version1: str, version2: str) -> int:
        v1 = version1.split('.')
        v2 = version2.split('.')
        n1 = len(v1)
        n2 = len(v2)
        n=max(n1,n2)
        for i in range (n):
            if i < n1:
                i1 = int(v1[i])
            else:
                i1 = 0
            if i < n2:
                i2 = int(v2[i])
            else:
                i2 = 0
            if i1!=i2:
                if i1 > i2:
                    return 1
                elif i1<i2:
                    return -1
        return 0 
class Solution:
    def compareVersion(self, version1: str, version2: str) -> int:
        nums1 = version1.split('.')
        nums2 = version2.split('.')
        n1, n2 = len(nums1), len(nums2)
        
        # compare versions
        for i in range(max(n1, n2)):
            i1 = int(nums1[i]) if i < n1 else 0
            i2 = int(nums2[i]) if i < n2 else 0
            if i1 != i2:
                return 1 if i1 > i2 else -1
        
        # the versions are equal
        return 0 
  • 思想

  • 备注

https://leetcode-cn.com/problems/compare-version-numbers/

42. 滑动窗口最大值

  • 题目
    给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
    返回滑动窗口中的最大值。
  • 代码
class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        res = []
        queue = collections.deque()
        for i, num in enumerate(nums):
            if queue and queue[0] == i - k:
                queue.popleft()
            while queue and nums[queue[-1]] < num:
                queue.pop()
            queue.append(i)
            if i >= k - 1:
                res.append(nums[queue[0]])
        return res
  • 思想
    利用双端队列记录当前滑动窗口的元素索引
    队列最左侧元素记录滑动窗口中最大元素的索引
    遍历数组:
    如果队列最左侧索引已不在滑动窗口范围内,弹出队列最左侧索引
    通过循环确保队列的最左侧索引所对应元素值最大
    新元素入队
    从第一个滑动窗口的末尾索引开始将最大值存储到结果res中
  • 备注

https://leetcode-cn.com/problems/sliding-window-maximum/

43. 第一个只出现一次的字符(飞书)

  • 题目
    在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例:
s = "abaccdeff"
返回 "b"
s = "" 
返回 " "
  • 代码
class Solution:
    def firstUniqChar(self, s: str) -> str:
        d = {}
        for i in s:
            d[i]= i not in d
        for j in d:
            if d[j]:
                return j
        return " "
  • 思想
    用键值对保存,没出现过的话,就保存true,出现过的话就是false,遍历一遍然后就重新遍历,第一个为true的,就是结果。如果都没有,就返回空。
  • 备注

https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/

44. 字符串的统计字符串

  • 题目
    给定一个字符串str,返回str的统计字符串。例如“aaabbbbcccd”的统计字符串为“a_3_b_4_c_3_d_1”。
示例1
输入
offerofferzainaliiiiii
输出
o_1_f_2_e_1_r_1_o_1_f_2_e_1_r_1_z_1_a_1_i_1_n_1_a_1_l_1_i_6
  • 代码
def getCountString(str1):
    if str1 == None or str1 == '':
        return ''
    res = str1[0]
    num = 1
    for i in range(1, len(str1)):
        if str1[i] == str1[i-1]:
            num += 1
        else:
            res = res + '_' + str(num) + '_' + str1[i]
            print(res)
            num = 1
    return res + '_' + str(num)
  • 思想

  • 备注

45. 模拟键盘的输出逻辑

  • 题目:有一个键盘,只有a-z 26个英文字母的输入键, 现在发现有两个按键坏了,按下会发生特定的结果
    按下i键=退格,会消除掉上一个输入字母
    按下o键=撤回,会撤销掉上一步的操作
    要求实现一个方法,模拟键盘的输出逻辑
  • 代码:
def test(data):
    list = []
    list_ext = []
    for i in data:
        if i =="i":
            if list !=[]:
                list_ext = list.copy()
                list.pop()
        elif i=="o":
            list_ext,list = list,list_ext
        else:
            list_ext = list.copy()
            list.append(i)
    return "".join(list)
  • 思想:
    定义两个数组,一个用来执行新的操作,一个用来记录上一次操作,以便回退。

46. 下一个排列

  • 题目:
    实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
    如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
    必须 原地 修改,只允许使用额外常数空间。
示例 1:
输入:nums = [1,2,3]
输出:[1,3,2]
示例 2:
输入:nums = [3,2,1]
输出:[1,2,3]
示例 3:
输入:nums = [1,1,5]
输出:[1,5,1]
  • 代码:
class Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        i = len(nums)-2
        while i>=0 and nums[i]>=nums[i+1]:
            i-=1
        if i >=0:
            j = len(nums)-1
            while j > 0 and nums[j]<=nums[i]:
                j-=1
            nums[i],nums[j]=nums[j],nums[i]
        left = i+1
        right=len(nums)-1
        while left<right:
            nums[left],nums[right]=nums[right],nums[left]
            left+=1
            right-=1
        return nums
  • 思路:

将一个左边的「较小数」与一个右边的「较大数」交换,以能够让当前排列变大,从而得到下一个排列。同时要让这个「较小数」尽量靠右,而「较大数」尽可能小。当交换完成后,「较大数」右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。

首先,从右开始向左遍历,出现的第一个非升序的数字[4,5,2,6,3,1],2,索引为i。
然后从右开始向左遍历找到第一个比i大的数的索引3,为j。因为第一步中从右向左都是升序的,所以按顺序第一个比i大的数,就是最接近i的大数。
然后他俩互换位置[4,5,3,6,2,1],然后将索引i右边的数重新升序排列[4,5,3,1,2,6]。

https://leetcode-cn.com/problems/next-permutation/

47. 移动零

  • 题目:
    给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

  • 代码:
    方法一:
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        j = 0 
        for i in range(len(nums)):
            if nums[i]!=0:
                nums[j]=nums[i]
                j+=1
        while j<=len(nums)-1:
            nums[j]=0
            j+=1
        return nums
  • 思想:
    遍历数组,如果数不为0,就从头顺序放置,遍历完数组后,用零补齐数组。
    方法二:快排思想
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        j=0
        for i in range(len(nums)):
            if nums[i]!=0:
                nums[i],nums[j]=nums[j],nums[i]
                j+=1
        return nums
  • 思想:
    以0为分界点,首先j=0,但是不确定nums[j]是0,但是没关系,遍历数组,i和j是同步增长的,但是当索引i的元素为0时,i就会比j多1,因为没走进if里,当再遇到索引i的元素不为0时,就将nums[i],nums[j]互换,j+1,这时候nums[j]为0了,

https://leetcode-cn.com/problems/move-zeroes/

实现 strStr()-字符串匹配

  • 题目:
    实现 strStr() 函数。
    给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

48. 求n的阶乘末尾0的个数

  • 题目
    输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2。
  • 代码
def zeronums(num):
    count=0
    for i in range(num+1):
        print(i)
        while i>0 and i%5==0:
            count+=1
            i=i/5
    return count
  • 思想
    一个数的阶乘末尾是0的话,必须有5与2相乘得到,2的个数一定比5多,所以求出阶乘的各个数中5的因子个数即可
  • 备注

49 判断给定数是否是2的幂次

  • 题目
    给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
    如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。
示例 1:
输入:n = 1
输出:true
解释:20 = 1
  • 代码
class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        return n>0 and n&(n-1)==0
  • 思想
    按位与
    在这里插入图片描述

  • 备注

50 最长公共前缀

  • 题目
    编写一个函数来查找字符串数组中的最长公共前缀。
    如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
  • 代码
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs)==0:
            return ""
        for i in range(len(strs[0])):
            s1 = strs[0][i]
            for j in range(1,len(strs)):
                if i==len(strs[j]) or strs[j][i]!=s1:
                    return strs[0][0:i]
        return strs[0]
  • 思想
    纵向扫描
    首先,将第一个字符串作为标准s1,i的循环用来纵向遍历到字符串的第几个元素,j的循环用来遍历第几个字符串。如果第j个字符串的长度与i相同,则说明已经超过了第j个字符串的长度,则返回strs[0][0:i],如果strs[j][i]!=s1,则返回
  • 备注

https://leetcode-cn.com/problems/longest-common-prefix/solution/pythonchui-zhi-sao-miao-fa-by-mu-qian-ruo-chi/

51整数反转

  • 题目
    给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
    如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
    假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
  • 代码
class Solution:
    def reverse(self, x: int) -> int:
        if 0<=x<10:
            return x
        res =""
        flag = 0
        if x<0:
            flag = 1
            x = -x
        while x>0:
            res+=str(x%10)
            x = x//10
        if flag:
            res = -int(res)
        return 0 if int(res)<-2**31 or int(res) > 2**31-1 else int(res)
  • 思想

  • 备注

https://leetcode-cn.com/problems/reverse-integer/

52 替换空格

  • 题目
    请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
  • 代码
class Solution:
    def replaceSpace(self, s: str) -> str:
        list = []
        for i in s:
            if i==" ":
                list.append("%20")
            else:
                list.append(i)
        return "".join(list)
  • 思想

  • 备注

https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/

53 字符串变形

  • 题目
    字符串中包括大写英文字母、小写英文字母、空格。
    输入描述:
    给定一个字符串s以及它的长度n(1≤n≤500)
    返回值描述:
    请返回变形后的字符串。题目保证给定的字符串均由大小写字母和空格构成。
示例1
输入:
"This is a sample",16
复制
返回值:
"SAMPLE A IS tHIS"
  • 代码
class Solution:
    def trans(self, s, n):
        stack = []
        i = n-1
        while i >= 0:
            stack.append(s[i])
            i -= 1
        i= j = 0
        while i<n:
            while i<n and stack[i]!=" ":
                i+=1
            stack[j:i]=reversed(stack[j:i])
            while i<n and stack[i]==" ":
                i+=1
            j = i
        return "".join(stack).swapcase()
class Solution:
    def trans(self, s, n):
        # write code here
        s = s.swapcase()
        result = s.split(" ")
        return " ".join(result[::-1])
  • 思想

  • 备注

https://www.nowcoder.com/practice/c3120c1c1bc44ad986259c0cf0f0b80e?tpId=117

54. 最大数

  • 题目
    给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。
    注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。
示例 1:
输入:nums = [10,2]
输出:"210"
示例 2:
输入:nums = [3,30,34,5,9]
输出:"9534330"
  • 代码
class Solution:
    def largestNumber(self, nums: List[int]) -> str:
        nums = "".join(sorted(map(str, nums),key=cmp_to_key(lambda x,y:((x+y) < (y+x)) - ((x+y) > (y+x)))))
        return nums if nums[0] != '0' else '0'
class Solution:
    #先把nums中的所有数字转化为字符串,形成字符串数组 nums_str
    #比较两个字符串x,y的拼接结果x+y和y+x哪个更大,从而确定x和y谁排在前面;将nums_str降序排序
    #把整个数组排序的结果拼接成一个字符串,并且返回
    def largestNumber(self, nums: List[int]) -> str:
        nums_str=list(map(str,nums))
        compare=lambda x,y: 1 if x+y<y+x else -1
        nums_str.sort(key=functools.cmp_to_key(compare))
        res=''.join(nums_str)
        if res[0]=='0':
            res='0'
        return res
  • 思想

https://leetcode-cn.com/problems/largest-number/solution/fu-xue-ming-zhu-zhuan-cheng-zi-fu-chuan-mm2s6/

  • 备注

key参数是一个很棒的设计。能把事情变得简单高效。说它简单是因为只需要提供一个单参数函数来提取或者计算一个值作为比较大小的标准即可,在排序的时候,python会基于两个key,但是那一阶段的计算发生在C语言那一层,这样会比调用用户自定义的python比较函数更快。

student_tuples = [
        ('john', 'A', 15),
        ('jane', 'B', 12),
        ('dave', 'B', 10),
]
sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

python3不支持比较函数,在一些接受key的函数中(例如sorted,min,max,heapq.nlargest,itertools.groupby),key仅仅支持一个参数,就无法实现两个参数之间的对比,采用cmp_to_key 函数,可以接受两个参数,将两个参数做处理,比如做和做差,转换成一个参数,就可以应用于key关键字之后。

例如:
from functools import cmp_to_key 
L=[9,2,23,1,2]
sorted(L,key=cmp_to_key(lambda x,y:y-x))
输出:
[23, 9, 2, 2, 1]

55.数组中重复的数字

  • 题目
    找出数组中重复的数字。
    在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:23 
  • 代码
class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        d = {}
        for i in range(len(nums)):
            if nums[i] not in d:
                d[nums[i]]=1
            else:
                return nums[i]
        return None
class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        d = set()
        for i in range(len(nums)):
            d.add(nums[i])
            if len(d)<=i:
                return nums[i]
        return None
  • 思想

  • 备注

https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/

56.根据数组中数字出现的次数排序

  • 题目
    给你一个整数数组 nums ,请你将数组按照每个值的频率 升序 排序。如果有多个值的频率相同,请你按照数值本身将它们 降序 排序。
    请你返回排序后的数组。
示例 1:
输入:nums = [1,1,2,2,2,3]
输出:[3,1,1,2,2,2]
解释:'3' 频率为 1'1' 频率为 2'2' 频率为 3
  • 代码
def aa(arr):
    d = {}
    for i in range(len(arr)):
        if arr[i] not in d:
            d[arr[i]]=1
        else:
            d[arr[i]]+=1
    new_d = sorted(d.items(),key = lambda x:x[1])
    list = []
    for nums in new_d:
        list+=([nums[0]]*nums[1])
    return list
输入:arr = [2,3,5,2,3,5,7,3]
输出:[7, 2, 2, 5, 5, 3, 3, 3]
new_d = sorted(d.items(),key = lambda x:x[1],reverse=True)
输入:arr = [2,3,5,2,3,5,7,3]
输出:[3, 3, 3, 2, 2, 5, 5, 7]
new_d = sorted(d.items(),key =  lambda x:(x[1],-x[0]))
输入:arr = [2,2,2,4,4,4,1,6]
输出:[6, 1, 4, 4, 4, 2, 2, 2]
如果有多个值的频率相同,请你按照数值本身将它们 降序 排序。 

  • 思想

  • 备注

https://leetcode-cn.com/problems/sort-array-by-increasing-frequency/

57.第三大的数

  • 题目
    给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。
示例 1:
输入:[3, 2, 1]
输出:1
解释:第三大的数是 1
  • 代码
class Solution:
    def thirdMax(self, nums: List[int]) -> int:
        a = b = c = float('-inf')
        for i in nums:
            if i>a:
                c,b,a=b,a,i 
            elif i>b and i!=a:
                c,b=b,i 
            elif i>c and i!=a and i!=b:
                c = i 
        if c==float('-inf'):
            return a
        else:
            return c
  • 思想
    float(“INF”)表示为正无穷;
    float(“-INF”)表示负无穷
  • 备注

https://leetcode-cn.com/problems/third-maximum-number/

问题

  • 题目

  • 代码

  • 思想

  • 备注

待解决

  1. str1,str2这两个字符串,输出str1中包含str2的最小子串长度 同时要求编写测试用例

  2. 返回一个英文句子中最后一个单词的长度

  3. 快排的原理、思想、是怎么实现的、时间复杂度、时间复杂度来源于什么、有什么办法改进吗

  4. 排列组合问题(0,1,2,3,4,5,选4,组合成四位数的个数)

  5. m,n个元素的数组nums,nums正序排列,找中位数

  6. 数组转换成数字的最大值

  7. 递归实现n的阶乘

  8. 移除一组字符串中出现次数最少的

  9. 如"3+2*{1+2*[-4/(8-6)+7]}” 实现字符串四则运算,返回整型结果

  10. 空格替换,将空格替换为其他字符

  11. 从原地地址拷贝n个长度的数据都另外一个地址。
    https://www.nowcoder.com/practice/e96f1a44d4e44d9ab6289ee080099322?tpId=117&tqId=703&tab=answerKey

  12. 鸡兔同笼,一半的兔子抬起一半的脚,问鸡和兔数量的组合有哪些?

  • 题目

  • 代码

  • 思想

  • 备注

问题

  • 题目

  • 代码

  • 思想

  • 备注

几种排序

快速排序
class Solution:
    def MySort(self , arr ):
        # write code here
        def quick(left, right):
            if left >= right:
                return arr
            pivot= left
            i = left
            j = right
            while i < j:
                while i < j and arr[j] > arr[pivot]:
                    j -= 1
                while i < j and arr[i] <= arr[pivot]:
                    i += 1
                arr[i], arr[j] = arr[j], arr[i]
            arr[pivot], arr[j] = arr[j], arr[pivot]
            quick(left, j - 1)
            quick(j + 1, right)
            return arr
        return quick(0, len(arr)- 1)
def kuaipai(arr,left,right):
    if left>=right:
        return arr
    i = left
    j = right
    key = left
    while i <j:
        while i<j and arr[j]>arr[key]:
            j-=1
        while i<j and arr[i]<=arr[key]:
            i+=1
        arr[i],arr[j]=arr[j],arr[i]
    arr[key],arr[i]=arr[i],arr[key]
    kuaipai(arr,left,i-1)
    kuaipai(arr,i+1,right)
    return arr
并归排序

归并排序,采用是分治法,先将数组分成子序列,让子序列有序,再将子序列间有序,合并成有序数组。
算法描述:
把长度为n的输入序列分成长度 n/2的子序列;
对两个子序列采用归并排序;
合并所有子序列。

def merge_sort(nums):
    if len(nums) <= 1:
        return nums
    mid = len(nums) // 2
    # 分
    left = merge_sort(nums[:mid])
    right = merge_sort(nums[mid:])
    # 合并
    return merge(left, right)


def merge(left, right):
    res = []
    i = 0
    j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            res.append(left[i])
            i += 1
        else:
            res.append(right[j])
            j += 1
    res += left[i:]
    res += right[j:]
    return res
冒泡排序

冒泡排序时针对相邻元素之间的比较,可以将大的数慢慢“沉底”(数组尾部)
内层循环:把数组中最小的那个往上冒,冒的过程就是和他相邻的元素交换。这个冒的过程就是内循环。控制每一轮里的每一个比较步骤。
外层循环:控制排序的轮数。经过了一个冒的过程,可以使一个最小的元素冒出来,如果数组里面有 n 个元素,就得冒 n-1 次。

def bubble_sort(nums):
    n = len(nums)
    for i in range(n):
        for j in range(1,n-i):
            if nums[j-1]>nums[j]:
                nums[j-1],nums[j]=nums[j],nums[j-1]
    return nums
插入排序

每次将一个数字插入一个有序的数组里,成为一个长度更长的有序数组,有限次操作以后,数组整体有序。
插入排序是前面已排序数组找到插入的位置。
步骤,把第一个数当做已经排好序的数组,从数组第二个数nums[i]开始,与前一个数比较,如果前一个数nums[i-1]比nums[i]大,则他俩换位置,然后i向前移动,nums[i]逐个与前面的数比较,直至找到它应该在的位置。

def insertion_sort(nums):
    for i in range(1,len(nums)):
        while i > 0 and nums[i-1]>nums[i]:
            nums[i-1],nums[i]=nums[i],nums[i-1]
            i-=1
    return nums
选择排序

这应该最符合人类思维的排序方法,工作原理,首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
步骤:
两层循环,外层循环保证从头开始每个数都是按顺序从小到大排好的,内层循环来一一比较把较小的往前放。

def selection_sort(nums):
    for i in range(len(nums)):
        for j in range(i,len(nums)):
            if nums[i]>nums[j]:
                nums[i],nums[j]=nums[j],nums[i]
    return nums

一些简单的算法

水仙花数
  • 题目
    如果一个 3 位各位数字的立方和,则称这个数为水仙花数。例如:153 = 1^3 + 5^3 + 3^3,因此 153 就是一个水仙花数,那么问题来了,求1000以内的水仙花数(3位数数等于其)
  • 代码
def shuixianhua(num):
    list=[]
    for i in range(100,num):
        s = sum([int(j)**len(str(i)) for j in str(i)])
        if s==i:
            list.append(i)
    return list
  • 思想
    遍历100-num之间的数字i,要把i先转化为字符串,因为字符串可以挨个取值,然后将其三位数子都做立方(四位数是四次方以此类推)计算后求和,如果和为其本身,则为水仙花数
  • 备注
九九乘法表
  • 题目

  • 代码

def chengfabiao():
    for i in range(1,10):
        for j in range(1,i+1):
            print("%s * %s = %-2s"%(i, j, i*j), end="    ")
        print()

在这里插入图片描述

  • 思想
    两层循环。
    print(“%s * %s = %-2s”%(i, j, i*j), end=" “)加上end=” "的目的是,本来每次打印一个都会换行,这样就不换行了,每个之间隔开。
    -2%s的意思是,个位数也占两格,左对齐
    print()是换行
  • 备注
排序去重
  • 题目
    问题1.对列表a 中的数字从小到大排序
    问题2.排序后去除重复的数字
    a = [1, 6, 8, 11, 9, 1, 8, 6, 8, 7, 8]
  • 代码
# 方法1
b = sorted(a) # 不改变a的序列
print(a)#[1, 6, 8, 11, 9, 1, 8, 6, 8, 7, 8]
print(b)#[1, 1, 6, 6, 7, 8, 8, 8, 8, 9, 11]
# 方法2
a.sort() # 改变a的序列
print(a)[1, 1, 6, 6, 7, 8, 8, 8, 8, 9, 11]
# set 集合去重,集合本身不能有重复
c = set(a)
print(c)#{1, 6, 7, 8, 9, 11}
  • 思想

  • 备注

列表翻转

如果有一个列表a=[1,3,5,7,11]
问题:1如何让它反转成[11,7,5,3,1]
2.取到奇数位值的数字,如[1,5,11]

  • 代码
# 反转 用到切片
a = [1,3,5,7,11]
print(a[::-1])
# 取奇数位置
print(a[::2]
  • 思想
    -1代表反转,2代表步长
  • 备注
完全数
  • 题目
    如果一个正整数等于除它本身之外其他所有除数之和,就称之为完全数。
    例如:6是完全数,* 因为6 = 1+2+3;
    下一个完全数是28 = 14+7+4+2+1。
    求1000以下的完全数
  • 代码
for i in range(1,1000):
    res = []
    for j in range(1,i):
        if i%j==0:
            res.append(j)
    if sum(res)==i:
        print(i)
  • 思想

  • 备注

list of dic 写入txt文件
  • 题目
    一个数据list of dict如下
    a = [ {“xx1”: “123456”}, {“xx2”: “123456”}, {“xx3”: “123456”},]
    写入到本地一个txt文件,内容格式如下:
    xx1,123456
    xx2,123456
    xx3,123456
  • 代码
a = [{"xx1": "123456"}, {"xx2": "123456"}, {"xx3": "123456"}]
for i in a:
	print(i.keys())
	for j in i.keys():
		print(j)
		with open("zuoye7.txt", "a", encoding="utf-8") as fp:
			fp.write("%s,%s\n"%(j, i[j]))
  • 思想

  • 备注

队列第一个数字放到第三个位置
  • 题目
    已知一个队列,如: [1, 3, 5, 7], 如何把第一个数字,放到第三个位置,得到: [3, 5, 1, 7]
  • 代码
a = [2,5,1,7,4]
a.insert(3,a[0])
print(a[1:])
  • 思想

  • 备注

统计列表中小于0的数
  • 题目
    统计在一个队列中的数字,有多少个正数,多少个负数,如[1, 3, 5, 7, 0, -1, -9, -4, -5, 8]
  • 代码
a = [1, 3, 5, 7, 0, -1, -9, -4, -5, 8]
b = [i for i in a if i > 0]
print("正数个数:%s"%len(b))
c = [i for i in a if i < 0]
print("负数个数:%s"%len(c))
  • 思想
    列表生成式
  • 备注
两个list合并
  • 题目
    a = [1, 2, 3, 4, 5]
    b = [“a”, “b”, “c”, “d”, “e”]
    如何得出c = [“a1”, “b2”, “c3”, “d4”, “e5”]
  • 代码
c=[str(i)+str(j) for i,j in zip(a,b)]
print(c)
  • 思想

  • 备注

题目
  • 题目
    写一个小程序:控制台输入邮箱地址(格式为 username@companyname.com),
    程序识别用户名和公司名后,将用户名和公司名输出到控制台。
    要求:
  1. 校验输入内容是否符合规范(xx@yy.com), 如是进入下一步,如否则抛出提 示"incorrect email format"。
    注意必须以.com 结尾
  2. 可以循环“输入–输出判断结果”这整个过程
  3. 按字母 Q(不区分大小写)退出循环,结束程序
    ‘’’
  • 代码
import re
while True:
text = input("Please input your Email address:")
if text.upper() == "Q": # lower()小写 s.upper()大写
quit()
if re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.com$',text):
# print('Email address is Right!')
username = re.findall("^(.+?)@", text)
  • 思想

  • 备注

题目
  • 题目

  • 代码

  • 思想

  • 备注

题目
  • 题目

  • 代码

  • 思想

  • 备注

题目
  • 题目

  • 代码

  • 思想

  • 备注

题目
  • 题目

  • 代码

  • 思想

  • 备注

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值