1.给出一个32位的有符号整数,实现整数中每位上的数字进行反转 ---> python3
- 将整数转为字符串,进行反转,后再恢复为整数
class Solution(object):
# 本题的思路就是先判断给定整数x的正负情况,把符号首先给提取出来
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
# 定义用来标记给定整数x的正负情况,若x>=0, 则flag=1;反之,则flag=-1
flag = 1 if x >= 0 else -1
abs_x = abs(x)
x_str = str(abs_x) # 将abs(x)变成字符串
reverse_x_str = x_str[::-1] # 将字符串x_str反转
reverse_x_int = int(reverse_x_str) * flag # 最后恢复成整数
if -2 ** 31 <= reverse_x_int <= 2**31 - 1:
return reverse_x_int
else:
return 0
if __name__ == "__main__":
x = 231
reverse_x = Solution().reverse(x)
print(reverse_x)
- 正常整数方法实现,利用余数*10累加的方法完成。需要注意的是,python对整数除法采用“向下取整”机制,所以正数和负数要区别运算。
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
num = 0
if x == 0:
return 0
if x < 0:
x = -x
while x != 0:
num = num*10 + x%10
x = x//10 # 此处注意要用‘//’取整
num = -num
else:
while x != 0:
num = num*10 + x%10
x = x/10
if num>pow(2,31)-1 or num < pow(-2,31): # 判是否出界
return 0
return num
2.判断一个数是否是回文数。回文数是指正序(从左到右)和倒序(从右到左)读都是一样的数
def is_huiwen(x):
if x >= 0:
x_str = str(x)
x_reverse = x_str[::-1]
x_int = int(x_reverse)
if x == x_int:
return True
else:
return False
else:
return None
# print('负数没有回文数!')
x = 1524
print(is_huiwen(x))
3.给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
示例 3: 示例 4: 示例 5:
输入: "IX" 输入: "LVIII" 输入: "MCMXCIV"
输出: 9 输出: 58 输出: 1994 解释: M = 1000, CM = 900, XC = 90, IV = 4.
4.编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。
示例 1: 示例 2:
输入: ["flower","flow","flight"] 输入: ["dog","racecar","car"]
输出: "fl" 输出: "" 解释: 输入不存在公共前缀。
只需要比较逐个字母ASCII码值,谁先出现小于的话,则为最小值 ,比较到最后则为最大值的存在,可以使用print()或者ipython测试
class Solution(object):
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if not strs: # 判断是否为空
return '' # 在使用max和min的时候已经把字符串比较了一遍
s1 = min(strs) # 当前列表的字符串中,每个字符串从第一个字母往后比较直至出现ASCII码 最小的字符串
s2 = max(strs) # 当前列表的字符串中,每个字符串从第一个字母往后比较直至出现ASCII码 最大的字符串
for i, c in enumerate(s1): # 使用枚举变量s1字符串的每个字母和下标
if c != s2[i]: # 比较是否相同的字符串,不相同则使用下标截取字符串
return s1[:i]
return s1
if __name__ == '__main__':
s = Solution()
print(s.longestCommonPrefix(["flower", "flow", "flight"]))
print('123', s.longestCommonPrefix(["dog", "racecar", "car"]))
5.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例: 输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
6.给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 : 给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
说明: 为什么返回数值是整数,但输出的答案是数组呢?请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
方法1:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
for i in range(len(nums)-1, 0, -1):
if nums[i] == nums[i-1]: nums.pop(i)
return len(nums) 时间效率O(N^2)空间效率O(1),逆遍历可以防止删除某个元素后影响下一步索引的定位。每次删除数组元素会引发大量的数据迁移操作,使用以下算法解题效率更高
7.搜索插入位置.给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。你可以假设数组中无重复元素。
示例 1: 输入: [1,3,5,6], 5 输出: 2
示例 2: 输入: [1,3,5,6], 2 输出: 1
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
n = len(nums)
if target in nums:
for i, num in enumerate(nums):
if num == target:
return i
else:
for i in range(n):
if target <= nums[0]:
return 0
elif target > nums[n-1]:
return n
else:
if target > nums[i] and target < nums[i+1]:
return i+1
8.报数.报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221
1 被读作 "one 1" ("一个一") , 即 11。
11 被读作 "two 1s" ("两个一"), 即 21。
21 被读作 "one 2", "one 1" ("一个二" , "一个一") , 即 1211。给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。注意:整数顺序将表示为一个字符串。
示例 1: 输入: 1 输出: "1"
示例 2: 输入: 4 输出: "1211"
循环含义
每次外循环含义为给定上一个人报的数,求下一个人报的数;每次内循环为遍历上一个人报的数
具体思路
先设置上一人为'1',开始外循环,每次外循环先置下一人为空字符串,置待处理的字符num为上一人的第一位,置记录出现的次数为1;开始内循环,遍历上一人的数,如果数是和num一致,则count增加。若不一致,则将count和num一同添加到next_person报的数中,同时更新num和count。别忘了更新next_person的最后两个数为上一个人最后一个字符以及其出现次数!
class Solution:
def countAndSay(self, n: int) -> str:
prev_person = '1'
for i in range(1,n):
next_person, num, count = '', prev_person[0], 1
for j in range(1,len(prev_person)):
if prev_person[j] == num:count += 1
else:
next_person += str(count) + num
num = prev_person[j]
count = 1
next_person += str(count) + num
prev_person = next_person
return prev_person
9.最大子序和.给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
#max(nums)
#sum(nums[0:3])
temp = []
n = len(nums)
for i in range(1, n+1): # 几个值相加
for j in range(0, n-i+1):
arrays = nums[j:j+i]
for array in arrays:
a = sum(array)
temp.append(a)
b = max(temp)
print(temp)
print(b)
1. 暴力求解
基本思路就是遍历一遍,用两个变量,一个记录最大的和,一个记录当前的和。时空复杂度貌似还不错......(时间复杂度 O(n)O(n),空间复杂度 O(l)O(l))
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
tmp = nums[0]
max_ = tmp
n = len(nums)
for i in range(1,n):
# 当当前序列加上此时的元素的值大于tmp的值,说明最大序列和可能出现在后续序列中,记录此时的最大值
if tmp + nums[i]>nums[i]:
max_ = max(max_, tmp+nums[i])
tmp = tmp + nums[i]
else:
#当tmp(当前和)小于下一个元素时,当前最长序列到此为止。以该元素为起点继续找最大子序列,
# 并记录此时的最大值
max_ = max(max_, tmp, tmp+nums[i], nums[i])
tmp = nums[i]
return max_
2. 分治法
分治法其他题解里讲的很清楚了。其实就是它的最大子序和要么在左半边,要么在右半边,要么是穿过中间,对于左右边的序列,情况也是一样,因此可以用递归处理。中间部分的则可以直接计算出来,时间复杂度应该是 O(nlogn)。代码如下:
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
n = len(nums)
if n == 1: #递归终止条件
return nums[0]
else:
max_left = self.maxSubArray(nums[0:len(nums) // 2]) #递归计算左半边最大子序和
max_right = self.maxSubArray(nums[len(nums) // 2:len(nums)]) #递归计算右半边最大子序和
#计算中间的最大子序和,从右到左计算左边的最大子序和,从左到右计算右边的最大子序和,再相加
max_l = nums[len(nums) // 2 - 1]
tmp = 0
for i in range(len(nums) // 2 - 1, -1, -1):
tmp += nums[i]
max_l = max(tmp, max_l)
max_r = nums[len(nums) // 2]
tmp = 0
for i in range(len(nums) // 2, len(nums)):
tmp += nums[i]
max_r = max(tmp, max_r)
#返回三个中的最大值
return max(max_right,max_left,max_l+max_r)
10.最后一个单词的长度。给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。
如果不存在最后一个单词,请返回 0 。
说明:一个单词是指由字母组成,但不包含任何空格的字符串。
示例:
输入: "Hello World"
输出: 5
s = "Hello World"
s = s.strip()
if len(s) != 0:
return len(s.split(' ')[-1])
else:
return 0
11.加一。给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1: 输入: [1,2,3] 示例 2: 输入: [4,3,2,1]
输出: [1,2,4] 输出: [4,3,2,2]
解释: 输入数组表示数字 123。 解释: 输入数组表示数字 4321。
遍历digits,判断每位是否为9,若不是则+1并返回,否则将此位置0;对于digits里全为9的情况,需要扩展list,并将首位置为1。
python
class Solution:
def plusOne(self, digits: [int]) -> [int]:
for i in range(len(digits)-1, -1, -1):
if digits[i] != 9:
digits[i] += 1
return digits
digits[i] = 0
digits[0] = 1
digits.append(0)
return digits
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
i = len(digits) - 1
while digits[i] == 9 and i >= 0:
i = i - 1
for j in range(i + 1, len(digits)):
digits[j] = 0
if i == -1:
digits.insert(0,1)
else:
digits[i] += 1
return digits
列表求和,加1,结果转化成列表
class Solution(object):
def plusOne(self, digits):
sums = 0
for i in range(len(digits)):
sums += 10**(len(digits)-1-i)*digits[i]
sums_str = str(sums + 1)
return [int(j) for j in sums_str]
12.爬楼梯。假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?注意:给定 n 是一个正整数。
示例 1: 示例 2:
输入: 2 输入: 3
输出: 2 输出: 3
解释: 有两种方法可以爬到楼顶。 解释: 有三种方法可以爬到楼顶
1. 1 阶 + 1 阶 1. 1 阶 + 1 阶 + 1 阶
2. 2 阶 2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
设爬 n个台阶有 f(n) 种可能:假设先爬1阶,剩下n-1 阶有f(n-1) 种可能;假设先爬2阶,剩下 n-2阶有 f(n-2) 种可能,因此爬n阶可以转化为两种爬n-1阶问题之和:f(n) = f(n-1) + f(n-2);
不难看出,这就是斐波那契数列公式,此题可转化为求斐波那契数列第n项。
PythonJava
class Solution:
def climbStairs(self, n: int) -> int:
a, b = 1, 1
for _ in range(n-1):
a, b = a + b, a
return a
13.删除排序链表中的重复元素。给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1: 示例 2:
输入: 1->1->2 输入: 1->1->2->3->3
输出: 1->2 输出: 1->2->3
n = len(l)
ll = []
for i in range(n):
if l[i] not in ll:
ll.append(l[i])
print(ll)
class Solution:
def deleteDuplicates(self, head: ListNode) -> ListNode:
if head == None or head.next== None:
return head
p = head
target = p.val
while True:
if p.next.val == target:
p.next = p.next.next
else:
target = p.next.val
p = p.next
if p.next is None:
break
return head