算法题目leetcode(1)

没事的时候,到letcode 看一下 算法题目 ,提高自己的编程思想, 总结一下,记录一下. 由于水平有限,如果发现有什么问题, 欢迎给我留言.

来看题吧. 

1 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1: 输入: 121 输出: true

示例 2:
输入: -121 输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

示例 3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。

#我的代码
class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        x = str(x)
        length = len(x)
        for i in range(length // 2):
            if x[i] != x[length - 1 - i]:
                return False
        return True

我的代码,就是先转成字符串, 然后,拿第一个字符,和最后一个比较,看是否相同. 如果不相同直接返回false , 否则继续比较 , 直到比较字符串的中间位置. 最后返回True  

来看下大神的代码

#其他人的代码

class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """       
        s = str(x)
        if s == s[::-1]:
            return True
        else:
            return False

其实思路类似吧,不过代码写的看起来,更加优雅. 在来看一下,另外一个大神写的.

扫描二维码关注公众号,回复: 2015246 查看本文章

# 大神代码
class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        return repr(x)[::-1] == repr(x)


2. 两数相加
给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@author: Frank 
@contact: [email protected]
@file: test_addTwoNumbers.py
@time: 2018/4/10 下午10:33
https://blog.csdn.net/suncherrydream/article/details/51894809

2. 两数相加
给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。

你可以假设除了数字 0 之外,这两个数字都不会以零开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

"""



# 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
        """

        preHead = ListNode(0)
        p = preHead

        carry = 0
        while l1 or l2 or carry:
            sum = (l1.val if l1 else 0) + (l2.val if l2 else 0) + carry

            carry = sum // 10
            p.next = ListNode(sum % 10)
            p = p.next

            l1 = l1.next if l1 else l1
            l2 = l2.next if l2 else l2

        return preHead.next


def traverse(l1):
    """

    :param l1:
    :return:
    """

    while l1:
        print(l1.val, sep='  ',end=',')
        l1 = l1.next




if __name__ == '__main__':


    solution = Solution()
    l1 = ListNode(2)
    l1.next = ListNode(4)
    l1.next.next = ListNode(3)
    l1.next.next.next = ListNode(9)

    l2 = ListNode(5)
    l2.next = ListNode(6)
    l2.next.next = ListNode(4)

    l3 = solution.addTwoNumbers(l1,l2)
    traverse(l3)

当然,这题主要考查链表 的操作,以及如何进位.  思路相 对比较清晰, 就是 拿两个链表的值 相加, 然后放到新的 链表里面, 同时要考虑是否需要进位的问题,如果大与10 ,就要考虑进位的问题.  还有就要考虑 链表的长度可能不一样, 当一个链表走到链表的尾部的时候,另一个链表ye'yao 参与计算的.  同时还有是否要进位. 看似简单, 实现起来, 还是花了不少的时间. 



三数之和

题目如下:

给定一个包含 n 个整数的数组 S,是否存在属于 S 的三个元素 a,b,c 使得 a + b + c = 0 ?找出所有不重复的三个元素组合使三个数的和为零。 注意:结果不能包括重复的三个数的组合。
例如, 给定数组 S = [-1, 0, 1, 2, -1, -4],
一个结果集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]


一开始 我想到的,就是下面的代码, 但是结果发现 有重复值

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from itertools import combinations
import random

numbs = [ random.randint(-99,99)  for _ in range(20) ]
# numbs = [-1, -2, 0, 5, 6, 7, 8, -4, -3,-12]
# numbs = [-1, -2, 0, 5, 6, 7, 8, 0,0,-4, -3,-12]

numbs.sort()

negative=  []
positive = []
results = []

for item in numbs:
    if item < 0:
        negative.append(item)
    elif item>= 0:
        positive.append(item)

print negative
print positive


# 在负数中取两个数字, 正数数组 取一根数字 
for idex,nega_i in enumerate(negative) :
	for nega_j in negative[idex+1:]:
		meddle_sum =  nega_i+nega_j

		for posi in positive:
			if  meddle_sum + posi ==0:
				zero_list = (nega_i,nega_j,posi)
				results.append(zero_list)

# 在负数数组中取一个数字, 正数数组中取两个数字
for  nega in negative:
	for idex , posi_i in enumerate(positive):
		for posi_j in positive[idex+1:]:
			if nega + posi_i + posi_j ==0:
				zero_list = (nega,posi_i,posi_j)
				results.append(zero_list)



# 对于非负数 数组中是否有 000 这种情况. 
zero_list = []
for  idx, posi in enumerate(positive):
	if posi ==0:
		zero_list.append(posi)

if len(zero_list)>=3:
	# print zero_list 
	# 求组合数 
	zero_obj = combinations(zero_list,3)
	for  combination in  zero_obj:
		# print combination
		results.append(combination)


print '*****'*25
for item in results:
	print item
# print  results

后来又改进了一下 

import  random
from itertools import combinations, permutations


class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        negative = []
        positive = []
        results = []

        for item in nums:
            if item < 0:
                negative.append(item)
            elif item >= 0:
                positive.append(item)

        # print negative
        # print positive

        # 在负数中取两个数字, 正数数组 取一根数字
        for idex, nega_i in enumerate(negative):
            for nega_j in negative[idex + 1:]:
                meddle_sum = nega_i + nega_j
                for posi in positive:
                    if meddle_sum + posi == 0:
                        zero_list = (nega_i, nega_j, posi)
                        if zero_list in results:
                            continue
                        results.append(zero_list)

        # 在负数数组中取一个数字, 正数数组中取两个数字
        for nega in negative:
            for idex, posi_i in enumerate(positive):
                for posi_j in positive[idex + 1:]:
                    if nega + posi_i + posi_j == 0:
                        zero_list = (nega, posi_i, posi_j)
                        if zero_list in results:
                            continue
                        results.append(zero_list)

        # 对于非负数 数组中是否有 000 这种情况.
        zero_list = []
        for idx, posi in enumerate(positive):
            if posi == 0:
                zero_list.append(posi)

        if len(zero_list) >= 3:
            results.append((0, 0, 0))
        return results


if __name__ == '__main__':
    nums = [random.randint(-99, 99) for _ in range(90)]

    # nums = [-1, -2, 0, 5, 6, 7, 8, -4, -3]
    # nums =[-1, 0, 1, 2, -1, -4]

    solution = Solution()

    results = solution.threeSum(nums)
    for item in results:
        print(item)
    # print(results)

思路分析:  我是想  a+b+c = 0  中 肯定是 1正 2负 ,  2正1负, 1正1负1零 , 全是0 .   我就先排序之后, 把 数组分成了 负数,和非负数两组,  从负数中取2个数字,从正数数组中取1个数字,看看和是不是0  如果是就把结果存起来,如果不是继续找. 这个就相当于使用穷举的方法来解决这个问题. 时间复杂度非常高. 提交代码后,直接timeout了...

后来看到网上的实现, 学习一下:

这样写起来, 时间复杂度大大降低了,学习一下. 

class Solution(object):

    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        results = []
        length = len(nums)

        for i, num in enumerate(nums):
            # 去除重复
            if i > 0 and num == nums[i - 1]:
                continue

            j = i + 1
            k = length - 1

            while j < k:
                # 去重
                if k < length - 1 and nums[k] == nums[k + 1]:
                    k = k - 1
                    continue

                if nums[j] + nums[k] + nums[i] < 0:
                    j = j + 1
                elif nums[j] + nums[k] + nums[i] > 0:
                    k = k - 1
                else:
                    zero_tuple = (nums[i], nums[j], nums[k])
                    # 找到结果,并且保存下来, ,j+1 , k -1 继续寻找.
                    results.append(zero_tuple)
                    j = j + 1
                    k = k - 1

        return results

思路如下: 考虑 先排序, 之后定义三个指针, nums[j] + nums[k] + nums[i]    

> 0  --->  k--

<0  ---> j++

==0  ---> 找到结果 , 同时 k--,  j ++



i ==0 时:


i ==1 时 


以此类推, 这样就可以找到所有的 等于0 的组合了, 非常棒, 学习一下. 


总结: 简单总结了LeetCode里面的简单的题目,可能里面也有不对的,如果有问题,欢迎指正, 这个文章,我以后定期更新,和大家一起学习算法, 提高自己的 编程能力, 和大家一起进步. 


如果你有更好的解决方法,可以评论给我,非常感谢 

分享快乐,留住感动.  2018-04-15 23:03:20  --frank

猜你喜欢

转载自blog.csdn.net/u010339879/article/details/79948527