刷题(解)之路--leetcode diary

## > 1418.旋转矩阵 给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。 不占用额外内存空间能否做到?

medium

示例 :
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]

链接:https://leetcode-cn.com/problems/rotate-matrix-lcci

class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.
        """
        n=len(matrix)
        for i in range(n//2):
            for j in range(n):
                matrix[i][j],matrix[n-i-1][j]=matrix[n-i-1][j],matrix[i][j]
        for i in range(n):
            for j in range(i):
                matrix[i][j],matrix[j][i]=matrix[j][i],matrix[i][j]
        return matrix

**## > 287.寻找重复数字medium
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

链接:https://leetcode-cn.com/problems/find-the-duplicate-number
输入: > [3,1,3,4,2]
输出: 3
输入: [1,3,4,2,2]
输出: 2 >
要求:

1.不能更改原数组(假设数组是只读的)。
2.只能使用额外的 O(1) 的空间。
3.时间复杂度小于 O(n2) 。
4.数组中只有一个重复的数字,但它可能不止重复出现一次。

解析1:使用快慢指针解决
因为nums的数字都是由1-n之间的,可以把数组抽象成一个环链表,接下来问题就是找到环链表的切入点。

我们需要快慢指针,同时从起点出发,慢指针一次走一步,快指针一次走两步,然后记录快慢指针相遇的点。
之后再用两个指针,一个指针从起点出发,一个指针从相遇点出发,当他们再次相遇的时候就是入口点了。

class Solution(object):
   def findDuplicate(self, nums):
       """
       :type nums: List[int]
       :rtype: int
       """
       low=nums[0]
       fast=nums[0]
       while True:
           low=nums[low]
           fast=nums[nums[fast]]
           if low == fast:
               break
       low,fast=nums[0],low
       while low!=fast:
           low=nums[low]
           fast=nums[fast]
       return low

解法2:二分查找
原数组不是有序,但是我们知道重复的那个数字肯定是 1 到 n 中的某一个,而 1,2…,n 就是一个有序序列。因此我们可以对 1,2…,n 进行二分查找。
给出mid=(right-left)//2,如果区间(left,mid)大于mid 的数超过了一半,那么重复的数肯定在左半边,反之在右半边。

class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        size = len(nums)
        left = 1
        right = size - 1

        while left < right:
            mid = left + (right - left) // 2

            cnt = 0
            for num in nums:
                if num <= mid:
                    cnt += 1
            if cnt > mid:
                # 重复的元素一定出现在 [left, mid] 区间里
                right = mid
            else:
                # if 分析正确了以后,else 搜索的区间就是 if 的反面
                # [mid + 1, right]
                left = mid + 1
        return left

作者:liweiwei1419
链接:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/er-fen-fa-si-lu-ji-dai-ma-python-by-liweiwei1419/

1.两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标

例如:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

解:用hash表来解决。

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] indexs = new int[2];

        HashMap<Integer,Integer> hash = new HashMap<Integer,Integer>();
        for(int i=0;i<nums.length;i++){
            if(hash.containsKey(nums[i])){
            indexs[0]=i;
            indexs[1]=hash.get(nums[i]);
            return indexs;             
            }
        hash.put(target-nums[i],i);
        }
    return indexs;
    }
}
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        d={}
        for i,j in enumerate(nums):
            minus=target-j
            if minus in d:
                return [d[minus],i]
            d[j]=i#key为num,value为index
        return None

202.快乐数easy
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。**

class Solution(object):
    def isHappy(self, n):
        """
        :type n: int
        :rtype: bool
        """
        men=set()
        while n != 1:
            n=sum([int(i)**2 for i in str(n)])
            if n in men:
                return False
            men.add(n)
        return True

你可能感兴趣的:(刷题(解)之路--leetcode diary)