Leetcode (10月)

10月份

01题TWO SUM(10.6)

所示

  • python暴力法
    报错运行时间超时,时间复杂度O(n^2),空间复杂度O(1)
l = len(nums)
        for i in range(l):
            if nums[i] > target :
                continue
            if i == l-1 :
                return 'error'
            for j in range(i+1,l):
                if nums[i]+nums[j] == target :
                    return [i,j]
  • python一遍哈希表,时间O(n),空间O(n)
def twoSum(nums, target):
    d = {}
    for i, n in enumerate(nums):
        if n in d:
            return [d[n], i]
        else:
            d[target-n]=i
    return (0,0)

因为没有查找value的方法,所以创建一个value-key 的dict,其中的d[target-num[i]] = i,在创建哈希表的同时就可以查找,找到键对应值的就为第一个数的位置

  • Java 一遍哈希表
    Map接口
    boolean containsKey(Object k)
    如果此映射包含指定键的映射关系,则返回 true
    Object get(Object k)
    返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int i = 0;i<nums.length;i++){
            int b = target - nums[i];
            if(map.containsKey(b)){
                return new int[] {map.get(b),i};
            }
            map.put(nums[i],i);
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

Python 中self 用法
主要是用于类中定义函数方便调用

02题Add Two Numbers(10.9)

You are given two non-empty linked lists representing two non-negative
integers. 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.

You may assume the two numbers do not contain any leading zero, except
the number 0 itself.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8 Explanation:
342 + 465 = 807.

这道题学习到了链表的操作,Java和python中利用引用,定义类来实现链表等数据结构的操作

  • python麻烦的
 def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        #进位        
        cur = 0
        item = z = ListNode(0)
        a = l1.val + l2.val
        cur = a//10
        item.next = ListNode(a%10)       
        item =item.next
        #巧妙的对z进行操作实现链表,下一个对应一个链
        while l1.next and l2.next:
            l1 = l1.next
            l2 = l2.next
            a = l1.val + l2.val
            b = a%10 + cur
            item.next = ListNode(b%10)
            cur = a//10+b//10
            item = item.next            
        if l1.next == None and l2.next == None :
            if cur>0:
                item.next = ListNode(cur)
            return z.next         
        elif l1.next == None:
            while l2.next:
                l2 = l2.next
                a = l2.val
                b = a + cur
                item.next = ListNode(b%10)
                cur = b//10
                item = item.next
            if cur>0:
                item.next = ListNode(cur)
            return z.next
        elif l2.next == None:
            while l1.next:
                l1 = l1.next
                a = l1.val
                b = a + cur
                item.next = ListNode(b%10)
                cur = b//10
                item = item.next
            if cur>0:
                item.next = ListNode(cur)
            return z.next
  • python别人的
class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        temp = z = ListNode(0)
        cur = 0
        while l1 or l2 or cur:
            if l1:
                cur +=l1.val
                l1 = l1.next
            if l2:
                cur +=l2.val
                l2 = l2.next
            temp.next = ListNode(cur%10)
            temp = temp.next
            cur //=10    
        return z.next   
  • Java的
 public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
			ListNode z = new ListNode(0);
			ListNode p = l1,q = l2,temp = z;
			int cur = 0;
			while(p!=null || q!=null) {
				int x = (p!=null)? p.val:0;
				int y = (q!=null)? q.val:0;
				int sum = x+y+cur;
				cur = sum/10;
				temp.next = new ListNode(sum%10);
				temp = temp.next;
				if(p!=null) {
					p = p.next;
				}
				if(q!=null) {
					q = q.next;
				}
    	}
			if(cur>0) {
				temp.next = new ListNode(cur);
			}
		return z.next;
		
}

03题(10.10)Longest Substring Without Repeating Characters

  • python暴力(超时)
    对于每一个函数的任务要明确,算法思想要少漏洞
def lengthOfLongestSubstring(s):
    """
    :type s: str
    :rtype: int
    """
    max = 0
    for i in range(len(s)):
        for j in range(i+1,len(s)+1):
            if isSubstring(s,i,j):
                length = j-i
                if(length>max):
                    max = length
    return max
    
def isSubstring(s,i,j):
    for m in range(i,j):
        if s[m] in s[m+1:j]:
            return False
    return True
  • python滑动窗口
	def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        a = ''
        j =0
        max = 0
        n = len(s)
        while(j<n):
            if(s[j] not in a):
                a = a+s[j]
                j = j+1
                if(max<len(a)):
                    max = len(a)
            else:
                a = a[1::]   
        return max      
  • python优化的滑动窗口
a = {}
        j = 0
        ans = 0
        for i in range(len(s)):
            if(s[i] in a):
                j = max(a[s[i]],j)
            a[s[i]] = i+1
            ans = max(ans,i-j+1)
        return ans

04题Median of Two Sorted Arrays(10.13)

m个 num1 i处分开
n个 num2 j处分开

1、i + j =m-i +n - j(或:m-i+n-j+1) n>m j = (m+n+1)/2
2、A[i-1]<=b[j] b[j-1]<=A[i]
二叉树搜索:
imin=0,imax= m,i = (imin+imax)/2

def findMedianSortedArrays(self, A, B):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        m = len(A)
        n = len(B)
        if m>n:
            A,B,m,n = B,A,n,m
        if n == 0:
            return error
        imin = 0
        imax = m
        x = (m+n+1)//2
        while(imin<=imax):
            i = (imin+imax)//2
            j = x-i
            if i<m and B[j-1]>A[i] :
                imin = i+1
            elif i>0 and  A[i-1]>B[j]:
                imax = i-1
            else:
                if i == 0: maxleft = B[j-1]
                elif j == 0: maxleft =A[i-1]
                else : maxleft = max(A[i-1],B[j-1])
                    
                if(m+n)%2 == 1:
                    return maxleft
                
                if i == m: minright = B[j]
                elif j == n: minright = A[i]
                else: minright = min(A[i],B[j])
                    
                return (maxleft+minright)/2.0

05题Longest Palindromic Substring

  • 中心扩展算法:从回文的中心开始找,对所有字符遍历,中心有两种可能:单个字符,以及挨着的相等字符 时间O(n2)
def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        n = len(s)
        start,end = 0,0
        for i in range(n):
            len1 = self.palindromic(s,i,i)
            len2 = self.palindromic(s,i,i+1)
            L = max(len1,len2)
            if(L>end-start):
                start = i - (L-1)//2
                end = i + L//2
        return s[start:end+1]
        
        
    def palindromic(self,s,i,j):
        L,R = i,j
        while(L>=0 and R<len(s) and s[L] == s[R]):
            L -= 1
            R += 1
        return R-L-1
  • Manacher 算法
    时间复杂度O(N)的专门解决回文的算法
  1. 算法分析

由于回文分为奇偶回文,处理比较麻烦,在每个字符前后都加上一个符号,从而变成奇数

s =‘abcd’      变为   s = '#a#b#c#d'

回文具有对称性质,pal(i)以i为中心的最大回文半径
在这里是图片描述
图中为以id为中心的回文,mx是回文的边界,我们想要得到以i为中心的最大回文半径,可以通过对j(i关于id的对称点)求解得到 ------j = 2*id - i

if(i<mx)
	p[i] = min(p[2*id-i],mx-i)
	若 p[2*id-i] == mx-i
		i还可以再往两边增加

以上通过P[j],可以快速得到对称的回文数,减少时间复杂度

  1. 马拉车代码
class Solution:
    def longestPalindrome(self,s): 
        ss = ''                     #装入加了#号的新字符串
        for i in s:
            ss = ss+'#'
            ss = ss+i
        ss = ss+'#' 
        p = [0]*2001                #表示以i为中心的最长回文字符串半径
        start,end,maxlen,mx = 0,0,0,0  #mx是以id为中心的回文最右边,start end最长的开始和结束

        for i in range(len(ss)):
            if(i<mx):         
                p[i] = min(p[2*id-i],mx-i)       #如果在id回文的边界之内,则可以借鉴对称位置的值
            else:
                p[i] = 1
            while((i - p[i])>=0 and i+p[i]<len(ss) and ss[i-p[i]] == ss[i+p[i]]):   #在已知基础上看还有没有其他值
                p[i] += 1
            if(mx<i+p[i]):                      #更新id和mx
                id = i
                mx = i+p[i]
            if(maxlen<(p[i]-1)):               #如果最大长度替换原来的
                maxlen = p[i]-1
                start = i+1-p[i]
                end = i+p[i]-1

        return ss[start:end+1].replace('#','')

10、Container With Most Water(10.19)

暴力法python o(n2)超时

m = 0
        long = len(height)
        for i in range(long-1):
            for j in range(i+1,long):
                high = min(height[i],height[j])
                s = (j-i)*high
                if(m<s): m = s
        return m

由两边向中心

	def maxArea(self, height):
		end = len(height)-1
        start = 0
        max = 0
        while(start<end):
            s = (end-start)*min(height[start],height[end])
            if(max<s): max = s
            if(height[start]<height[end]):
                start += 1
            else: 
                end -=1
                
        return max

15.3SUM(10.20)

思路:简单的暴力法肯定会超时

换思路,先排序(通过排序解决重复问题),选出一个数后取反-c,如果遇到相等的直接跳过,然后从右边剩下的里面找a,b,从两边向中间找,a如果相等直接跳过,直到
a+b = -c

def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        l,ans = len(nums),[]
        nums.sort()
        for i in range(l-2):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            c = nums[i]*-1
            a = i+1 
            b = l-1
            while a<b :
                if nums[a]+nums[b] == c:
                    ans.append([nums[i],nums[a],nums[b]])
                    a += 1
                    while a<b and nums[a] == nums[a-1]:
                        a += 1
                elif nums[a] + nums[b] < c :
                    a += 1
                else:
                    b -= 1
        return ans

17.Letter Combinations of a Phone Number(10.21-11.8)

思路:通过输入的数字,得到要输出的key值——num,循环遍历num,将对应的value相加
两个数组相加最简单,多个数组很难操作
通过新建一个空数组的方式,循环进行两数组相加

  • python
	n = len(digits)
        phone = {2:'abc',3:'def',4:'ghi',5:'jkl',6:'mno',7:'pqrs',8:'tuv',9:'wxyz'}
        res = ['']
        if n == 0:
            return []
        for i in digits:
            num = phone[int(i)]  
            newres = []
            for a in num:
                for b in res:
                    newres.append(b+a)
            res = newres
        return res
  • java一样思路的解法
    (其中java直接赋值是将地址给了)
public List<String> letterCombinations(String digits) {
        List<String> ans = new ArrayList<String>();
		List<String> newans = new ArrayList<String>();
		String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
		if(digits.isEmpty()) return ans ;
		ans.add("");
		for(int i=0;i<digits.length();i++) {
			int x = Character.getNumericValue(digits.charAt(i));		
			newans.clear();
			for(char s : mapping[x].toCharArray())
				{				
					for(String t: ans) {					
						newans.add(t+s);					
					}					
				}
			ans.clear();
			ans.addAll(newans);			
		}
		return ans; 
    }
  • java另一个思路

remove(),直接去掉第一个元素并取出,一直循环直到所有的元素都加上了新的

public static List<String> letterCombinations(String digits) {
		LinkedList<String> ans = new LinkedList<String>();
		String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
		if(digits.isEmpty()) return ans ;
		ans.add("");
		for(int i=0;i<digits.length();i++) {
			int x = Character.getNumericValue(digits.charAt(i));
			while(ans.peek().length()==i){
				String t = ans.remove();
				for(char s : mapping[x].toCharArray())
					ans.add(t+s);
			}
		}
		return ans;
        
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值