1. Two Sum
1. Two Sum
题目描述: 给一个整型数组,和一个目标值,用数组里面的两个数加起来正好等于它,找到这两个值的数组下标。
解题思路: 简单题,直接两层循环去找。不过还是有坑,数组的数不能自己加自己如给定[3,2,4] , 6,需要返回[1,2]而不是[0,0]。
AC代码:
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(len(nums)-1):
if target-nums[i] in nums[i+1:]: # 如果有target-nums[i]在i后面,就可以直接返回结果了
return [i,i+1+nums[i+1:].index(target-nums[i])]
2. Add Two Numbers
题目描述: 给两个用链表表示的数,如 (2 -> 4 -> 3) + (5 -> 6 -> 4) 表示 342 + 465 = 807 ,把他们加起来,同样返回一个链表表示结果,如(7 -> 0 -> 8)表示 807.
解题思路: 简单题,分别从两个链表中把数提取出来,然后加起来,再把结果生成一个链表返回。
AC代码:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
num1,num2,tmp = 0,0,1
while l1:
num1 += tmp*int(l1.val)
tmp *= 10
l1 = l1.next
tmp = 1
while l2:
num2 += tmp*int(l2.val)
tmp *= 10
l2 = l2.next
ans = num1+num2
new = ListNode(0)
tmp1 = new
while ans:
tmp1.val = ans%10
ans = int(ans/10)
if ans:
tmp1.next = ListNode(0)
tmp1 = tmp1.next
return new
3. Longest Substring Without Repeating Characters
3. Longest Substring Without Repeating Characters
题目描述: 给定一个字符串S,找出最长的 无重复字符 的子串并返回。
解题思路: 看着就比较像找回文串的做法,尝试用n2 复杂度的暴力算法解,超时,失败。暂时想不到更好的算法。看了别的的代码,觉得好神奇。起点从0开始,用一个字典去记录每一个字符出现的位置,再次出现时更新这个值,并且如果它比起点更大,说明是从起点开始第二次碰到的相同字符,这时候就更新一下最大值。否则即使碰到了重复元素,由于更新了起点,如果是从新起点开始第一次碰到的,就不管,当前最大值加一,直到再次碰到它,就更新最大值。
AC代码
class Solution(object):
def lengthOfLongestSubstring(self, s):
dct = {}
max_so_far = curr_max = start = 0
for index, i in enumerate(s):
if i in dct and dct[i] >= start: # 判断是否是从起点开始第二次碰到的字符
max_so_far = max(max_so_far, curr_max) # 更新最大值
curr_max = index - dct[i] # 更新当前最大值
start = dct[i] + 1 # 更新起点
else:
curr_max += 1
dct[i] = index # 更新每个字符的出现位置
return max(max_so_far, curr_max)
4. Median of Two Sorted Arrays
4. Median of Two Sorted Arrays
题目描述: 给定两个升序排列的数组,找出他们合在一起的中位数。
解题思路: 看这个题目之前被他的难度给惊到了,标的是hard的难度,但是怎么看这个题都是个简单题啊。解法就类似于两个升序数组的合并,但是这个题只需要找到中位数,并不需要合并,因此用几个变量记录好位置就行了。到达中间位置就记录下答案。中间位置有两者可能,为了简便,就把中间位置只有的一个的时候也记成两个,然后加两次,就行了。
AC代码:
class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
len1,len2 = len(nums1),len(nums2)
mid = [int((len1+len2)/2),int((len1+len2-1)/2)]
i,j,ans,step = 0,0,0,0
while i< len1 or j < len2 or step <= mid[1]:
if i >= len1:
tmp = nums2[j]
j += 1
elif j >= len2:
tmp = nums1[i]
i += 1
elif nums1[i] >= nums2[j]:
tmp = nums2[j]
j += 1
else:
tmp = nums1[i]
i += 1
if step == mid[0]:
ans += tmp
if step == mid[1]:
ans += tmp
step += 1
return float(ans)/2
5. Longest Palindromic Substring
5. Longest Palindromic Substring
题目描述: 给定一个字符串,找出最大的回文子串。
解题思路: Manacher 算法,最后注意把找到的子串提取出来。算法详解
AC代码:
class Solution {
public:
string longestPalindrome(string s) {
string s1 = "";
int radius[2010]={-1,};
int i,R = -1,C = -1,len;
len = s.size();
for (i = 0 ; i < len ; i ++ ) //初始化拓展序列
s1 += '#',s1 += s[i]; s1 += '#';
int ans = 0;
for (i = 0; i <= 2*len ; i++) {
radius[i] = R > i ? min(radius[2*C-i],R-i+1) : 1 ;
while(i+radius[i] <= 2*len && i - radius[i] > -1)
{
if(s1[i-radius[i]] != s1[i+radius[i]]) break;
radius[i] ++;
}
if(i + radius[i] > R)
{
R = i + radius[i]-1;
C = i;
}
ans = radius[ans] >= radius[i] ? ans : i ;//更新最大值
}
string ans_s = s1.substr(ans-radius[ans]+1,2*radius[ans]-1);
string new1="";
for (i = 0 ; i < ans_s.size() ; i ++)
if(ans_s[i] != '#')
new1 += ans_s[i];
return new1;
}
};
6. ZigZag Conversion
题目描述: 文字描述不太清,就是给一个字符串S,根据一定的排列规定重新组合生成一个新字串。
解题思路: 简单题,直接模拟,注意行的变化即可,按行变化依次将原串中的字符丢进每行的串里就行,最后拼接一下
AC代码:
class Solution(object):
def convert(self, s, numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
if numRows == 1: return s #行数为一直接返回原串
res = [""]*numRows #初始化N行空串
line = numRows
i,lenth = 0,len(s)
try: #用try块是免得去检查i的边界 越界了抛异常直接返回结果就行了
while True:
if line == numRows: #一个周期的开始 依次丢一个字符到各自的行里去
for j in range(numRows):
res[j] += s[i]
i += 1
line -= 1 #更新行号
elif line == 1:
line = numRows #周期结束 更新行号重新开始
else:
res[line-1] += s[i] #根据行号把字符丢到他应该去到的行
i += 1
line -= 1
except:
return "".join(res) #拼接一下字符串并返回结果
7. Reverse Integer
题目描述: 反转数字如 -123返回 -321 ,1200 返回 12. 如果结果超出了32位整型数的范围,返回0。
解题思路: 简单题,先转化成字符串然后倒置过来再判断是否带负号,然后再转化成数字,判断是否越界。
AC代码:
class Solution(object):
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
if len(str(x)) == 1: return x
ans = int("".join(reversed(list(str(x)[1:])))) # 先转化成str再倒置再转化成int
ans = ans*10+int(str(x)[0]) if str(x)[0].isdigit() else -ans # 判断符号
return ans if -2147483648 <= ans <= 2147483648 else 0 # 判断是否越界,并返回结果
8. String to Integer (atoi)
挺简单一题,给定一个字符串 S 转成整数,就是坑点太多
- 空串 “” 返回 0
- 正常 如“345” 返回 345
- 小数 如 “3.14159” 返回 3
- 负数 如 “-1314” 返回 -1314
- 数字加文字 如“abc def -123” 返回 -123
- 文字加数字 如“123 abc def” 返回 0
- 各种奇怪组合 如“-5-” 返回 -5 如“ -00012a45” 返回 -45
- 不能转化的 返回 0 如“abc” “+__+” “words” “a123” “b 233”
- 大于 231-1 的直接输出232 -1 小于 -(231-1) 的 直接输出 -(231 -1)
解题思路
第一个想到用python,其他的后续再补,先一个S.split() 干掉前后空格并且进行拆分字符串,保留第一个元素就行。
如果保留下来的元素不带数字,转化会直接抛异常,就返回0
如果带有数字则还有许多坑要填, 如“ -00012a45” “-233-” 只需截取前半部分再转化
浮点数如“3.14”用int转化也会抛异常所以先float()转化一下再int()转过来
转化成功之后再检查上下边界是否有超
AC代码:
class Solution(object):
def myAtoi(self, str):
"""
:type str: str
:rtype: int
"""
try:
new = str.split()[0] #预处理字符串 留下第一部分 如果是空串直接抛异常返回0
for i in range(1,len(new)): #检查坑点
if not new[i].isdigit() and new[i-1].isdigit():
new = new[:i] #删掉尾巴奇怪的字符如“-5a20” 留下“-5”
break
ans = int(float(new)) #浮点数如“3.14”直接用int()转会报错所以转个两次
if ans > 0x7fffffff : return 0x7fffffff #最大边界范围判断
elif ans < -0x80000000: return -0x80000000 #最小边界范围判断
else: return ans
9. Palindrome Number
题目描述: 判断是否是个回文数字如121是,-121不是。
解题思路: 字符串倒置匹配
AC代码:
class Solution(object):
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
return str(x) == str(x)[::-1]