Preface:刷题。
问题描述:
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
题目理解:
遍历序列,考虑到在本身的序列中找到另外一个数,加上去等于target,显然对另外一个数用上字典是最佳的。一旦剩下的序列中有重复元素时便不能将其作为字典,可以采用将target-number[i]动态地加入字典,遍历寻找时,若剩下的序列中的元素在字典中未找到,便将target-number[i],继续加入到字典。
coding:
def twoSum(num, target): num_dict = {} for i in range(len(num)): if num[i] not in num_dict: num_dict[target - num[i]] = i + 1 else: return num_dict[num[i]], i + 1 return -1, -1 num = [0,4,3,0] target = 0 print twoSum(num,target)
问题描述:
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
问题理解:
两个非负整数序列,相加,得到新的序列。342+564=807,故输出7->0->8。需考虑到边界问题:0+0=0以及大数+大数=大数。由于已经定义了ListNod()类,线下测试的时候,可以new L1,L2对象。首先大数相加问题,可化为字符串先存储,然后转为long型的数字相加。
coding:
#!/usr/bin/env python # coding=utf-8 ''' File Name:Add_Two_Numbers_2.py Author:shifeng Mail:[email protected] Created Time:六 1/23 11:24:01 2016 ''' 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 """ str1 = "" while l1: str1+=str(l1.val)# put 2->4->3 transform to "243" l1 = l1.next str2 = "" while l2: str2+=str(l2.val) l2 = l2.next #print str1,str2 num = long(str1[::-1])+long(str2[::-1])#add long("342")+long("465") #we get 807,now we need to output 7->0->8 s = str(num)[::-1] l3 = ListNode(s[0]) t = [ListNode(i) for i in s] if len(t)-1<=0:#if only one ele, we need to think about len(t)-1. return [num] else: for i in range(0,len(t)-1): t[i].next = t[i+1] return t[0] l1=ListNode(2) temp=ListNode(4) temp.next=ListNode(3) l1.next=temp l2 = ListNode(5) temp = ListNode(6) temp.next = ListNode(4) l2.next = temp print l1.val,l1.next.val,l1.next.next.val print l2.val,l2.next.val,l2.next.next.val l3 = ListNode(1) l3.next = ListNode(8) l4 = ListNode(0) a = Solution() t = a.addTwoNumbers(l1,l2) t1 = a.addTwoNumbers(l3,l4)
问题描述
Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.
问题理解
简而言之就是找出字符串无重复字母的最长字串的长度。对每个字符都有个最长字串的长度。第start字符开始,向后找,若是后面的第end个字符,在前面出现了,那么第start字符的[start,end+1]这段就是整个string以字符第start字符开始的最长字串的长度,然后遍历下个字符,不过计算长度时直接从end+1作为起始的边界就可以了。
coding:
class Solution(object): def lengthOfLongestSubstring(self,s): maxlen = 0 left = 0#边界left。 d = {} for i,ch in enumerate(s): if ch in d and d[ch]>=left:#更改边界条件,如果后面的字符出现在了字典d中,而且其位置大于左边界,那么边界改为这个重复的字符的下一个位置,等下次遍历时,重复且超过这个边界才改。 left = d[ch] + 1 d[ch] = i#对每个字符都进行遍历存到字典中。 maxlen = max(maxlen, i - left+1)#以每个字符开始的最长字串的长度。 return maxlen solution = Solution() s1 = "abcabcbb" s2 = "bbbbb" print solution.lengthOfLongestSubstring(s1) print solution.lengthOfLongestSubstring(s2)
问题描述
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)P A H NA P L S I I GY I RAnd then read line by line: "PAHNAPLSIIGYIR"Write the code that will take a string and make this conversion given a number of rows:string convert(string text, int nRows);convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".
问题理解
将字符串按照竖折线写重新排列。如下图所示。
figure 6 :zigzag
coding
class Solution(object): def convert(self, s, numRows): if numRows==1: return s step = 2*numRows - 2 ret = s[::step] #取出转换后的第一行 for i in range(1,numRows-1):#剔除第0行和最后一行,进行处理。 for j in range(i,len(s),step):#从i行开始,step为步长。 ret+=s[j]#对于step进行处理。 if j+2*(numRows-i-1)
问题描述
Reverse digits of an integer.
Example1: x = 123, return 321
Example2: x = -123, return -321
问题理解
逆转整数,若是有符号,则符号不变。考虑超长数字,是否包含数字,是否为一个数字等边界即可。
coding
class Solution: # @return an integer def reverse(self, x): x_str = str(x) x_list = list(x_str) y_str = "" large = 2**31 #考虑特别长的数 if "-" not in x_list: #是否包含负号 if len(x_list)==1: #是否只有一个数 y_str=x_list[0] else: for i in range(len(x_list)-1,-1,-1): y_str += x_list[i] y_str = int(y_str) if long(y_str)>=large: y_str = 0 #------------------------------------- else: if len(x_list)==2: y_str+=x_list[1] else: for i in range(len(x_list)-1,0,-1): y_str += x_list[i] if long(y_str)>=large: y_str = 0 y_str = "-"+str(y_str) y_str = int(y_str) #转为数字类型 return y_str
问题描述
Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
问题理解
将字符串转为整数。考虑的因素需要包括字符串前面的空格,是否包含正负号,遇到非数字字符,那么取该字符之前的部分,超出边界,返回边界值。
coding
class Solution(object): def myAtoi(self,s): s = s.strip() if not s: return 0 symbol = 1 if s[0]=="-":#考虑正负号, symbol = -1 s=s[1:]#去掉第一个字符。 elif s[0]=="+": symbol = 1 s = s[1:] ret = 0 MAX_INT = 2147483647 MIN_INT = -2147483648 overborder = False for i in range(0,len(s)): if not s[i].isdigit():#遇到非字符就返回。 break else: ret = ret*10+int(s[i]) if not MIN_INT<=ret*symbol<=MAX_INT:#考虑边界问题。 overborder = True if overborder: return MAX_INT if symbol==1 else MIN_INT else: return ret*symbol
问题描述
Determine whether an integer is a palindrome. Do this without extra space.
问题理解
判断一个整数是否为回文数,即逆着些也是相同。python一句可破。化为字符串,然后字符串和逆着字符串比较即可。
coding
class Solution(object): def isPalindrome(self, x): """ :type x: int :rtype: bool """ return str(x)[::-1]==str(x)
10.
11.
问题描述
Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
问题理解
数字1到3999,转换为罗马数字。1000以上单独考虑,也不必单独考虑,撸主为方便。因为有个规则,字母不能超过3次,也即对于包含4、9的数字需要特殊处理。考虑小于4的,等于4,等于9,5到8这四部分即可。
coding
class Solution(object): def intToRoman(self,num): val = [[900,500,400,100],[90,50,40,10],[9,5,4,1]] syb = [["CM","D","CD","C"],["XC","L","XL","X"],["IX","V","IV","I"]] if num>3999 or num<1: return "" st = "" st+="M"*(num/1000) num = num%1000 for i in range(len(val)): temp = num/val[i][3] if temp > 3: if temp == 4: st+=syb[i][2] elif temp==9: st+=syb[i][0] else: st+=syb[i][1]+(temp-5)*syb[i][3] else: st+=syb[i][3]*temp num = num%val[i][3] return st
问题描述
Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
问题理解
将一个罗马数转为正数。
coding
class Solution(object): def romanToInt(self,s): val = {"M":1000,"D":500,"C":100,"L":50,"X":10,"V":5,"I":1} ret = 0 for i in range(len(s)): if i>0 and val[s[i]]>val[s[i-1]]: ret+=val[s[i]] -2*val[s[i-1]]#在上次遍历的时候,加了一次s[i],故在这一次遍历的时候-s[i-1] else: ret+=val[s[i]] return ret
问题描述
Write a function to find the longest common prefix string amongst an array of strings.
问题理解
从一系列数组中,找到最长公共前缀字符串。将每个字符串进行切分(其实按照最短的那个字符串进行切分),取每个字符串的所有前缀,对所有字符串进行交集运算,若无返回"",若有返回最长的那个。
coding
class Solution(object): def longestCommonPrefix(self, strs): if not strs:#判断边界条件,是否为空。 return "" sset = set() str1 = strs[0] for i in range(len(str1)):#取其中一个的所有前缀子字符串,其他的与其做交集。 temp = str1[:i+1] sset.add(temp) results = set() for s in strs:#剩下的每个元素都将其与第一个进行交集运算。 tempset = set() for j in range(len(s)): temp = s[:j+1] tempset.add(temp) sset = tempset&sset if not sset:#对于空元素的,直接返回"",若有多个重复的,排序取长度最长的。 return "" return sorted(sset, key = lambda i:len(i), reverse=True)[0]
15.
问题描述
问题理解
coding
问题描述
Given a string containing just the characters
'('
,')'
,'{'
,'}'
,'['
and']'
, determine if the input string is valid.The brackets must close in the correct order,
"()"
and"()[]{}"
are all valid but"(]"
and"([)]"
are not.
问题理解
配对括号。撸主的想法是先去掉非括号字符,对左括号进栈,右括号出栈,一个临时列表即可实现。最后的temp列表为空表明其是合法的。
coding
class Solution(object): def isValid(self, s): """ :type s: str :rtype: bool """ if not s: return True c = [] d = {")":"(","]":"[","}":"{"} for ch in s: if ch in "()[]{}": c.append(ch) if len(c)%2!=0: return False temp=[]#temp作为一个栈,读入只包含左右括号的列表c,左括号进栈右括号出栈,最后为空即可。 if c[0] in d: return False for i in range(len(c)): if c[i] in d: if temp[-1]==d[c[i]]: temp.pop()#遇到了右括号而且前面一个是配对的左括号那么左括号出栈,否则错误。 else: return False else:#非右括号进栈。 temp.append(c[i]) if temp: return False else: return True
问题描述
Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
For example, given n = 3, a solution set is:
"((()))", "(()())", "(())()", "()(())", "()()()"
问题理解
产生2的n次方种圆括号序列,去掉不符合规范的。此为解法1。其二,根据组合数学里面的卡当数
coding
class Solution(object): def generateParenthesis(self, n): if n<1: return [] results = [] s = [] #深入优先产生左右括号,若是有括号数量大于左括号返回。 def dfs(): if len(s)>=2*n: if s.count("(")!=s.count(")"):#如果左右括号数量不一致不用考虑 pass else: flag = 1 for i in range(len(s)): temp = s[:i+1] if temp.count("(")
问题描述
Given a linked list, swap every two adjacent nodes and return its head.
For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
问题理解
成对交换两个节点,但是不能直接换值而是换节点。python的异常处理以及赋值交换可破。创建节点0,以节点0为整,交换其后面两个元素,当前节点不断变换,直到当前节点没有下一个节点出现异常时跳出循环,返回交换后的结果。
coding
class ListNode(object): def __init__(self,x): self.val = x self.next = None class Solution(object): def swapPairs(self, head): dum = ListNode(0) dum.next = head cur = dum#cur为需要调换两个节点之前的节点。 #n = 0 try: while True: pre,cur,nxt = cur,cur.next,cur.next.next#将0,1,2赋给临时变量。 pre.next,cur.next,nxt.next = nxt, nxt.next, cur #pre为0,pre.next需要为2,也即上步的nxt #cur为1,下次遍历时cur需要为1,并且1的next为3,也即2的next,为nxt的next, #nxt为2,2的next需要为1,也即是cur的值 #n+=1 #if n>1000: # break except: return dum.next s6 = ListNode(6) s5 = ListNode(5) s5.next = s6 s4 = ListNode(4) s4.next = s5 s3 = ListNode(3) s3.next = s4 s2 = ListNode(2) s2.next = s3 s1 = ListNode(1) s1.next = s2 a = Solution() head_new = a.swapPairs(s1) while head_new: print head_new.val head_new = head_new.next
问题描述
Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
For example,
Given input array nums = [1,1,2],
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.
问题理解
删除有序数组中的重复元素,返回删除后的结果,并且删除后前面的元素需要需要唯一,但不能用多余的空间。方案一,遍历,遇到重复的元素,将该重复的元素变为其后面的一个元素,一直变下去,不必移动后面的元素。方案二,若是遇到重复元素,不将其加到列表中,未通过,不知何因。
coding
class Solution(object): def removeDuplicates(self, nums): if not nums: return 0 ret = 1 for i in range(1,len(nums)): if nums[i]!=nums[i-1]: nums[ret] = nums[i] ret+=1 print nums,ret return ret a = Solution() nums = [1,1,2] a.removeDuplicates(nums) class Solution2(object): def removeDuplicates(self, nums): if not nums: return 0 nums = ["s"]+nums return len([nums[i] for i in range(1,len(nums)) if nums[i]!=nums[i-1]])
27.
28.
200.Number of Islands
Given a 2d grid map of '1'
s (land) and'0'
s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
暂且存个没法通过的版本。这题若是用python networkx包,则很好破,首先将矩阵转为二分图,行和列两部分,然后直接调用networkx包里面的函数number_connected_components,可破。只是leetcode似乎不能调用包。
import networkx as nx
class Solution:
# @param grid, a list of list of characters
# @return an integer
def numIslands(self, grid):
G = nx.Graph()
list_edges = []
num = 0
if not grid or not grid[0]:
num = 0
else:
m,n = len(grid),len(grid[0])
for i in m:
for j in n:
if grid[i][j]==1:
s="a"+str(j)
tuple_edge = (i,s)
list_edges.append(tuple_edge)
G.add_edges_from(list_edges)
num = nx.number_connected_components(G)
return num