目录
两数之和
预备知识
python中的enumerate()函数:
nums=['a','b','c']
for i, j in enumerate(nums):
print(i, j)
输出如下,可以输出从0开始的索引和列表的元素
![]()
python字典的键值对:
nums={'a':1, 'b':2, 'c':3}
nums['a']=4
print(nums['a'])
输出是4,字典的键值对是在中括号里给键然后可以根据键来查/改对应的值
nums={'a':1, 'b':2, 'c':3}
if 'a' in nums:
print(nums['a'])
else:
print('no a')
输出‘a’对应的值:1
字典可以用in来查找某个键是否在字典中
题目
给定一个整数数组
nums和一个整数目标值target,请你在该数组中找出 和为目标值target的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
解答
代码+详细注释:
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hm=dict() # 以键值对的形式存下nums中的索引和值,其中:键是nums中的元素,值是nums元素对应的索引
for i, num in enumerate(nums): # i是输入的数组nums的索引(从0开始),num是数组nums里面的元素
if target-num in hm: # 当找到两个数之和是target时,一个是num,那么另一个就是target-num
return [hm[target-num],i] # 返回找到的两个数的索引。其中因为当target-num已经在字典hm中了,所以它对应的索引比当前的num对应的索引(也就是i)要小,就写在前面
hm[nums[i]]=i # 把键值对 nums[i]:i 存入字典hm
return [] # 没找到就返回空列表
思路:
-
首先初始化一个空字典
hm,该字典用于以键值对的形式存储数组nums中的元素与对应索引的映射关系,其中字典的键是nums数组中的具体元素值,字典的值是该元素在nums数组中对应的索引位置。 -
接着通过
enumerate函数遍历nums数组,遍历过程中会同时获取到当前元素的索引i(索引从 0 开始递增)和对应的元素值num。 -
在每次遍历中,先进行关键的查找判断:计算目标值
target与当前元素num的差值(即target - num),然后检查该差值是否存在于字典hm中。这一步的逻辑是,若两数之和等于target,已知其中一个数是当前遍历到的num,那么另一个需要匹配的数就必然是target - num。 -
一旦查找到
target - num存在于字典hm中,说明已经找到了满足条件的两个元素,此时直接返回这两个元素的索引即可 —— 其中hm[target - num]是先存入字典的元素对应的索引(必然小于当前遍历到的元素索引i),因此将其放在前面,i放在后面。 -
若当前遍历的元素对应的匹配值
target - num不存在于字典中,则将当前元素nums[i]和其索引i作为键值对存入字典hm,以便后续遍历的元素进行匹配查找。 -
若整个数组遍历完毕后,仍未找到满足两数之和等于
target的两个元素,则返回一个空列表,表示不存在符合条件的解。
回文数
题目
给你一个整数
x,如果x是一个回文整数,返回true;否则,返回false。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,
121是回文,而123不是。
进阶:你能不将整数转为字符串来解决这个问题吗?
示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。
解答
class Solution:
def isPalindrome(self, x: int) -> bool:
if x<0 or (x%10==0 and x!=0): # 当x为负数时候肯定不是回文数(因为-不可能对称),当x的个位数字是0时候也不可能是回文数(因为0不能是首位)
return False
rn=0 # 记录一下反转后的数,奇数位的回文数劈开一半多一位再除以10等于剩下的数,偶数位的回文数劈开一半再反过来等于剩下的数
while(rn<x):
rn=x%10+rn*10 # 这样就可以把x的后半部分反过来了
x//=10 # 取x的个位,注意python中的整除是//而不是/
return (rn==x or rn//10==x)
判断一个给定的整数 x 是否为回文数(回文数指从正、反两个方向读取,数值完全相同的数,例如 121、11、1221 等)。
先通过特殊情况快速排除非回文数,再对整数的后半部分进行反转,最后将反转后的后半部分与剩余的前半部分对比,以此判断是否为回文数(无需反转整个整数,提升效率)。
1. 特殊情况预处理(快速排除非回文数)
首先判断两种必然不是回文数的情况,若满足任一情况,直接返回“false”:
(1)当 x 为负数时:因为负数的符号“-”无法与其他数字对称(例如 -121 反转后是 121-,并非原数),所以负数一定不是回文数;
(2)当 x 的个位数字是 0 且 x 不等于 0 时:回文数的首位数字不能为 0(例如 120 反转后是 021,即 21,与原数不相等),因此这类数也不是回文数。
2. 反转整数的后半部分
初始化一个变量 rn(用于存储反转后的后半部分数字)为 0,通过循环逐步提取 x 的末尾数字,构建反转后的后半部分:
(1)循环条件:当 rn(反转后的后半部分)小于 x(剩余的前半部分)时,继续循环(此条件可确保只反转后半部分,而非整个数字);
(2)反转逻辑:每次循环中,先通过“x%10”提取 x 的个位数字,再用“rn = 提取的个位数字 + rn*10”将该数字拼接到 rn 的末尾(实现后半部分的逐步反转);
(3)缩减 x:通过整数除法“x//=10”去掉 x 的个位数字(此时 x 逐渐保留前半部分,rn 逐渐构建反转后的后半部分)。
3. 对比判断是否为回文数
循环结束后,根据原整数的位数(奇数位或偶数位),分两种情况对比:
(1)若原数是偶数位:此时 rn(反转后的后半部分)应与剩余的 x(前半部分)完全相等(例如 1221,反转后半部分“21”得到“12”,剩余 x 为“12”,两者相等);
(2)若原数是奇数位:原数中间的数字不影响回文判断,此时需将 rn(反转后的后半部分,包含中间数字)除以 10 取整(去掉中间数字),再与剩余的 x(前半部分)对比(例如 121,反转后半部分“21”得到“121”,rn//10 为“12”,剩余 x 为“1”?此处修正:实际 121 循环后 rn=121,x=1,rn//10=12?不,重新梳理:121 循环过程:初始 rn=0,x=121;第一次循环 rn=1,x=12;第二次循环 rn=12,x=1;此时 rn=12 > x=1,循环结束。rn//10=1,与 x=1 相等,因此判断为回文数);
综上,若“rn 等于 x”或“rn 除以 10 取整后等于 x”,则 x 是回文数,返回“true”;否则返回“false”。
return str(x) == str(x)[::-1]
这是转换成字符串的写法
罗马数字转整数
题目
罗马数字包含以下七种字符:
I,V,X,L,C,D和M。字符 数值
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。给定一个罗马数字,将其转换成整数。
示例 1:
输入: s = "III"
输出: 3
示例 2:
输入: s = "IV"
输出: 4
示例 3:
输入: s = "IX"
输出: 9
示例 4:
输入: s = "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: s = "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
解答
class Solution:
chset={
'I':1,
'V':5,
'X':10,
'L':50,
'C':100,
'D':500,
'M':1000
} # 定义一个字典来用键值对对应符号和数值
def romanToInt(self, s: str) -> int:
ans=0 # 存储答案
for i, ch in enumerate(s): # 获得字符串s中的键和对应的索引
value=Solution.chset[ch] # 记录当前单个字符的值
if i<len(s)-1 and value<Solution.chset[s[i+1]]: # 如果下一个字符的值比当前字符的值大就减去当前字符的值。i是字符在s中的索引,s[i+1]是s中下一个位置的字符,然后再到chset中查找该字符对应的值。注意这里会先执行and前面的判断,再执行and后面的,所以如果顺序写错会显示索引超范围
ans-=value
else:
ans+=value
return ans
将给定的罗马数字字符串 s 转换为对应的整数(罗马数字通过特定字符组合表示数值,需遵循其加减规则完成转换,例如 "IX" 对应 9、"LVIII" 对应 58 等)。
先通过字典建立罗马字符与对应数值的键值对映射,方便快速查询单个字符的数值;再遍历罗马数字字符串,根据 “当前字符值小于下一个字符值则减当前值,否则加当前值” 的规则,累加计算最终的整数结果,无需复杂逻辑,高效完成转换。
-
建立字符 - 数值映射表定义一个字典
chset,将罗马数字的核心字符(I、V、X、L、C、D、M)作为键,对应的整数(1、5、10、50、100、500、1000)作为值,通过键值对形式存储,实现后续遍历中对单个罗马字符数值的快速查询。 -
初始化结果变量定义整数变量
ans并赋值为 0,用于存储罗马数字转换后的最终整数结果,后续遍历过程中通过加减操作更新该变量。 -
遍历字符串并计算结果遍历罗马数字字符串
s,同时获取每个字符的索引i和字符本身ch,按以下逻辑逐步更新结果:(1)查询当前字符数值:通过字典chset快速获取当前字符ch对应的数值,存入变量value;(2)判断加减规则:先判断当前索引是否合法(即i < len(s) - 1,确保存在下一个字符,避免索引超范围),再判断当前字符值是否小于下一个字符的数值(value < chset[s[i+1]])。若两个条件同时满足,说明当前字符是罗马数字中的 “减法组合”(如 I 在 V 前、X 在 L 前等),执行ans -= value(减去当前字符值);若不满足,则执行ans += value(加上当前字符值);(3)顺序遍历无遗漏:按索引顺序遍历字符串所有字符,确保每个字符都按规则参与计算,无遗漏或重复处理。 -
返回最终结果遍历结束后,变量
ans已存储罗马数字转换后的整数,直接返回ans即可得到最终转换结果。
Two Sum
Question
Given an array of integers
numsand an integertarget, return indices of the two numbers such that they add up totarget.You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
Solution
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hm = dict() # Store the indices and values from the nums array in the form of key-value pairs, where: the key is the element in nums, and the value is the corresponding index of that element in nums
for i, num in enumerate(nums): # i is the index of the input array nums (starting from 0), and num is the element in the array nums
if target - num in hm: # When two numbers that add up to the target are found, one is num, so the other one is target - num
return [hm[target - num], i] # Return the indices of the two found numbers. Since target - num is already in the dictionary hm, its corresponding index is smaller than the index of the current num (which is i), so it is placed first
hm[nums[i]] = i # Store the key-value pair (nums[i]: i) into the dictionary hm
return [] # Return an empty list if no such two numbers are found
Explanation:
First, initialize an empty dictionary hm, which is used to store the mapping relationship between the elements of the array nums and their corresponding indices in the form of key-value pairs. Here, the keys of the dictionary are the specific element values in the nums array, and the values of the dictionary are the corresponding index positions of those elements in the nums array.
Next, traverse the nums array using the enumerate function. During the traversal, we can simultaneously obtain the index i of the current element (the index increments starting from 0) and the corresponding element value num.
In each iteration of the traversal, first perform a key lookup check: calculate the difference between the target value target and the current element num (i.e., target - num), then check if this difference exists in the dictionary hm. The logic behind this step is that if the sum of two numbers equals target, and we already know one of the numbers is the currently traversed num, then the other number that needs to be matched must be target - num.
Once it is found that target - num exists in the dictionary hm, it indicates that we have found the two elements that meet the criteria. At this point, we can directly return the indices of these two elements — where hm[target - num] is the index of the element that was stored in the dictionary earlier (which is necessarily smaller than the index i of the currently traversed element), so it is placed first, and i is placed second.
If the matching value target - num corresponding to the currently traversed element does not exist in the dictionary, then store the current element nums[i] and its index i as a key-value pair in the dictionary hm, so that subsequent traversed elements can use them for matching and lookup.
If the entire array is traversed and we still have not found two elements whose sum equals the target, return an empty list, indicating that there is no solution that meets the criteria.
Palindrome Number
Question
Given an integer
x, returntrueifxis a palindrome, andfalseotherwise.
Example 1:
Input: x = 121
Output: true
Explanation: 121 reads as 121 from left to right and from right to left.
Example 2:
Input: x = -121
Output: false
Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
Example 3:
Input: x = 10
Output: false
Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
Solution
class Solution:
def isPalindrome(self, x: int) -> bool:
# When x is a negative number, it is definitely not a palindrome (because the minus sign cannot be symmetric). When the units digit of x is 0 (and x is not 0 itself), it is also not a palindrome (because 0 cannot be the leading digit of a number).
if x < 0 or (x % 10 == 0 and x != 0):
return False
# Record the reversed number. For a palindrome with an odd number of digits, if we split the number into two halves (with the middle digit included in the second half), dividing the reversed second half by 10 (integer division) will equal the first half. For a palindrome with an even number of digits, reversing the second half will equal the first half.
rn = 0
while (rn < x):
# This step reverses the second half of x digit by digit.
rn = x % 10 + rn * 10
# Remove the units digit of x. Note that in Python, integer division is done with // instead of /.
x //= 10
# If rn equals x (even number of digits) or rn // 10 equals x (odd number of digits), then x is a palindrome.
return (rn == x or rn // 10 == x)
Core Objective
To determine whether a given integer x is a palindrome (a palindrome is a number that reads the same forward and backward, e.g., 121, 11, 1221, etc.).
Overall Approach
First, quickly exclude non-palindromic numbers by checking special cases. Then reverse the second half of the integer, and finally compare the reversed second half with the remaining first half to judge if x is a palindrome. This method avoids reversing the entire integer, thus improving efficiency.
Detailed Steps
-
Preprocessing of Special Cases (Quick Exclusion of Non-Palindromes)First, check two scenarios where x is definitely not a palindrome. If either scenario is satisfied, directly return false:(1) When x is a negative number: The minus sign cannot be symmetric with other digits (e.g., reversing -121 gives 121-, which is not the original number), so negative numbers are never palindromes.(2) When the units digit of x is 0 and \(x \neq 0\): The leading digit of a palindrome cannot be 0 (e.g., reversing 120 gives 021, which is 21 and not equal to the original number), so such numbers are not palindromes either.
-
Reverse the Second Half of the IntegerInitialize a variable rn (used to store the reversed second half of the number) to 0, and gradually extract the last digit of x through a loop to construct the reversed second half:(1) Loop Condition: Continue the loop while rn (the reversed second half) is less than x (the remaining first half). This condition ensures that only the second half is reversed, not the entire number.(2) Reversing Logic: In each iteration, first extract the units digit of x using \(x\%10\), then append this digit to the end of rn with the formula \(rn = \text{extracted units digit} + rn \times 10\) (to achieve gradual reversal of the second half).(3) Reduce x: Remove the units digit of x using integer division \(x //= 10\). At this point, x gradually retains the first half, and rn gradually forms the reversed second half.
-
Comparison to Judge PalindromesAfter the loop terminates, perform the comparison in two cases based on the number of digits of the original integer (odd or even):(1) If the original number has an even number of digits: At this point, rn (the reversed second half) should be exactly equal to the remaining x (the first half). For example, for 1221, reversing the second half "21" gives "12", and the remaining x is "12" (they are equal).(2) If the original number has an odd number of digits: The middle digit of the original number does not affect the palindrome judgment. At this point, we need to perform integer division of rn (the reversed second half, which includes the middle digit) by 10 (to remove the middle digit), then compare the result with the remaining x (the first half). (For example, for 121: let’s re-examine the loop process. Initial state: \(rn = 0\), \(x = 121\); first iteration: \(rn = 1\), \(x = 12\); second iteration: \(rn = 12\), \(x = 1\). The loop terminates because \(12 > 1\). Then \(rn // 10 = 1\), which is equal to \(x = 1\), so 121 is judged as a palindrome.)
In summary, if \(rn = x\) or \(rn // 10 = x\), then x is a palindrome and we return true; otherwise, we return false.
Roman to Integer
Question
Roman numerals are represented by seven different symbols:
I,V,X,L,C,DandM.Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000For example,
2is written asIIin Roman numeral, just two ones added together.12is written asXII, which is simplyX + II. The number27is written asXXVII, which isXX + V + II.Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not
IIII. Instead, the number four is written asIV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written asIX. There are six instances where subtraction is used:
Ican be placed beforeV(5) andX(10) to make 4 and 9.
Xcan be placed beforeL(50) andC(100) to make 40 and 90.
Ccan be placed beforeD(500) andM(1000) to make 400 and 900.Given a roman numeral, convert it to an integer.
Example 1:
Input: s = "III"
Output: 3
Explanation: III = 3.
Example 2:
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
Example 3:
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
Solution
class Solution:
chset={
'I':1,
'V':5,
'X':10,
'L':50,
'C':100,
'D':500,
'M':1000
} # Define a dictionary to map Roman symbols to their corresponding integer values using key-value pairs
def romanToInt(self, s: str) -> int:
ans=0 # Store the final converted integer result (answer)
for i, ch in enumerate(s): # Get each character in string s and its corresponding index
value=Solution.chset[ch] # Record the integer value of the current single Roman character
# If the value of the next character is greater than the current character's value, subtract the current value from the answer.
# Here, i is the index of the current character in s, s[i+1] is the next character in s, and we look up its value in chset.
# Note: In Python, the conditions connected by "and" are evaluated in left-to-right order with short-circuit evaluation.
# So we first check if the index is valid (to avoid index out of range), then compare the values. If the order is wrong, an index out of range error will occur.
if i<len(s)-1 and value<Solution.chset[s[i+1]]:
ans-=value
else:
ans+=value
return ans
Core Objective
To determine whether a given integer x is a palindrome (a palindrome refers to a number that reads exactly the same when viewed both forward and backward, such as 121, 11, 1221, etc.).
Overall Approach
First, quickly exclude non-palindromic numbers by identifying special cases. Then, reverse the second half of the integer, and finally compare the reversed second half with the remaining first half to determine if x is a palindrome. This method avoids reversing the entire integer, thereby improving efficiency.
Detailed Steps
-
Preprocessing of Special Cases (Quick Exclusion of Non-Palindromes)First, check two scenarios where x is definitely not a palindrome. If either scenario is satisfied, directly return "false":(1) When x is a negative number: The minus sign "-" cannot be symmetric with other digits (for example, reversing -121 results in 121-, which is not the original number), so negative numbers are definitely not palindromes.(2) When the units digit of x is 0 and x is not equal to 0: The leading digit of a palindrome cannot be 0 (for example, reversing 120 results in 021, which is 21 and not equal to the original number), so such numbers are not palindromes either.
-
Reverse the Second Half of the IntegerInitialize a variable rn (used to store the reversed second half of the number) to 0, and gradually extract the last digit of x through a loop to construct the reversed second half:(1) Loop Condition: Continue the loop when rn (the reversed second half) is less than x (the remaining first half). This condition ensures that only the second half, rather than the entire number, is reversed.(2) Reversing Logic: In each loop iteration, first extract the units digit of x using "x%10", then append this digit to the end of rn with the formula "rn = extracted units digit + rn*10" (to achieve gradual reversal of the second half).(3) Reduce x: Remove the units digit of x using integer division "x//=10". At this point, x gradually retains the first half of the original number, while rn gradually constructs the reversed second half.
-
Comparison to Determine if It Is a PalindromeAfter the loop terminates, perform the comparison in two cases based on the number of digits of the original integer (odd or even):(1) If the original number has an even number of digits: At this point, rn (the reversed second half) should be exactly equal to the remaining x (the first half). For example, for 1221, reversing the second half "21" yields "12", and the remaining x is "12" (the two are equal).(2) If the original number has an odd number of digits: The middle digit of the original number does not affect the palindrome judgment. At this point, it is necessary to perform integer division of rn (the reversed second half, which includes the middle digit) by 10 (to remove the middle digit), then compare the result with the remaining x (the first half). (Note: Correction here - let's re-analyze the loop process for 121: Initial state: \(rn=0\), \(x=121\); First loop iteration: \(rn=1\), \(x=12\); Second loop iteration: \(rn=12\), \(x=1\); At this point, \(rn=12 > x=1\), so the loop terminates. \(rn//10=1\), which is equal to \(x=1\), thus 121 is judged as a palindrome.)
In summary, if "rn is equal to x" or "the result of rn divided by 10 (integer division) is equal to x", then x is a palindrome and we return "true"; otherwise, we return "false".

359

被折叠的 条评论
为什么被折叠?



