leetcode 解题报告(66-77)

66. Plus One

题目描述: 一个用数组表示的整数,加一,然后再返回新的数组。

解题思路: 水题,最简单的就是先变成整数然后加一再转成数组,当然也可以稍微麻烦一点,最后一位加一然后往前判断进位。

AC代码:

# python
class Solution(object):
    def plusOne(self, digits):
        return [int(i) for i in str(int("".join([str(i) for i in digits]))+1)]

67. Add Binary

题目描述: 两个用字符串表示的二进制数,加起来,返回结果的二进制表示字符串。

解题思路: 和上一题差不多,可以转整数加再转字符串,不过这题正好换一种方式写,直接加判断进位。

AC代码:

// C++
class Solution {
public:
    string addBinary(string a, string b) {
        if (a.size() < b.size())  swap(a,b);
        for(int i = b.size()-1 ; i >= 0 ; i --)
        {
           
            int j = a.size() - 1 - (b.size() - 1 - i);
            if(b[i] == '1')
            {
                int tmp = a[j]-'0' + b[i] -'0';
                if(tmp == 1)
                    a[j] = '1';
                if(tmp == 2)
                {
                    while(j>=0 && a[j] != '0')
                        a[j--] = '0';
                    if(j == -1 && a[0] == '0') 
                        a = '1' + a;
                    else
                        a[j] = '1';
                }
            }
        }
        return a;
    }
};

69. Sqrt(x)

题目描述: 计算一个数平方根,向下取整。

解题思路: 还是水题啊,二分的思想,找到一个值,使得平方小于等于x,而+1再平方就会大于x。

AC代码:

// c++
class Solution {
public:
    int mySqrt(int x) {
        long long l = 0 ,r = x,mid = x/2;
        while(mid*mid != x)
        {
            if ((mid*mid) < x && ((mid+1)*(mid+1) > x))
                return mid;
            if(mid*mid < x)
                l = mid+1;
            else
                r = mid-1;
            mid = (l+r)/2;
        }
        return mid;
    }
};

70. Climbing Stairs

题目描述: 跳台阶,N级台阶一次跳一格或者两格问跳到第N级有多少种方法。

解题思路: 这就是一个入门的dp问题,而且结果也是一个斐波那契数列,题目给的数据少,如果给的数据很大,就不简单了,还得用矩阵快速幂去算。

AC代码:

// c++
class Solution {
public:
    int climbStairs(int n) {
     long long ans[] = {1,1,2};
        for(int i = 3 ; i <= n ; i ++)
        {
            ans[0] = ans[1];
            ans[1] = ans[2];
            ans[2] = ans[0]+ans[1];
        }
        if(n < 2) return 1;
        return ans[2];
    }
};

71. Simplify Path

题目描述: 简化路径,类似linux里面的路径给出最简形式。

Example 1:

Input: "/home/"
Output: "/home"
Explanation: Note that there is no trailing slash after the last directory name.
Example 2:

Input: "/../"
Output: "/"
Explanation: Going one level up from the root directory is a no-op, as the root level is the highest level you can go.
Example 3:

Input: "/home//foo/"
Output: "/home/foo"
Explanation: In the canonical path, multiple consecutive slashes are replaced by a single one.
Example 4:

Input: "/a/./b/../../c/"
Output: "/c"
Example 5:

Input: "/a/../../b/../c//.//"
Output: "/c"
Example 6:

Input: "/a//bc/d//././/.."
Output: "/a/b/c"

解题思路: 模拟,先按‘/’分割每个文件夹,然后进到一个文件加就压到栈里,然后出一个文件加就弹出一个,‘.’或者’ '就直接pass。

AC代码:

# python
class Solution(object):
    def simplifyPath(self, path):
        partion = path.split("/")
        ans = []
        for i in partion:
            if i == '..':
                if ans:
                    ans.pop()
            elif i == '.' or i == '':
                pass
            else:
                ans.append(i)
        res = ""
        for i in ans:
            res += "/"+i
        if not res:
            return "/"
        return res


73. Set Matrix Zeroes

题目描述: 一个矩阵,要求把有0在的那一行和那一列都全部变成0,要求是不占用额外的空间,找到一个O(1)空间的解法。

解题思路: 题目了提示有n*m空间的解法,有m+n空间的解法,也就是说记录一下哪里有0。要用O(1)空间其实可以利用第一行和第一列来做一个标志位,把有0的地方,先把他的行首和列首置0,然后再用一个循环把行首列首的0所代表的行列置0,但是要特别注意第一个点也就是 0 0位置,因为他既是行首又是列首,所以还需要一个变量来记录一下。正好是占用了O(1)的空间。后来看了别人的写法,发现和我的如出一辙。

AC代码:

# python
class Solution(object):
    def setZeroes(self, matrix):
        matrix,c1,l1 = matrix,0,0
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j] == 0:
                    if i == 0: l1 = 1
                    if j == 0: c1 = 1
                    matrix[i][0] = 0
                    matrix[0][j] = 0
        for j in range(1,len(matrix[0])):
            if matrix[0][j] == 0:
                for i in range(len(matrix)):
                    matrix[i][j] = 0
        for i in range(1,len(matrix)):
            if matrix[i][0] == 0:
                for j in range(len(matrix[0])):
                    matrix[i][j] = 0
        if c1:
            for i in range(len(matrix)):
                matrix[i][0] = 0
        if l1:
            for i in range(len(matrix[0])):
                matrix[0][i] = 0
        return matrix

74. Search a 2D Matrix

题目描述: 在矩阵里找一个数,问能不能找到。矩阵行列都是按从小到大排序的。

Example 1:

Input:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 3
Output: true
Example 2:

Input:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 13
Output: false

解题思路: 上学期数据结构上级考试老师就给我们这题。当时没想到m+n的算法。想的是先搜索行,然后二分搜索行内的数。应该是n*log m的算法。还是不够高效,根据这个矩阵的特殊的性质其实可以发现从左下角走,可以直接确定目标值的方向,如果大于目标值往上找,如果小于目标值往右找。

AC代码:

# python
class Solution(object):
    def searchMatrix(self, matrix, target):
        if matrix == []: return False
        length = len(matrix[0])
        x,y = len(matrix)-1,0
        while x >= 0 and y < length:
            if matrix[x][y] == target:
                return True
            if matrix[x][y] > target:
                x -= 1
            elif matrix[x][y] < target:
                y += 1
        return False

75. Sort Colors

题目描述: 一个数组只有0 1 2 把0移到左边,1移到中间,2移到右边。

解题思路: 乍一看以为要手写个快排,因为题目说不能用库里的排序函数。后来想想不就三个数字比大小吗,直接先从头走一遍,把0换到最前面,在从0的后面一个位置开始走,把1挪到前面,2自然就到后面去了。类似于冒泡排序,遍历两次数组就能完成了。用一个c记录需要交换的位置。

AC代码:

// c++
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int c = 0;
        for (int i = 0 ; i < nums.size() ; i ++)
            if (nums[i] == 0)
                swap(nums[c++],nums[i]);
        for (int i = c ; i < nums.size() ; i ++)
            if (nums[i] == 1)
                swap(nums[c++],nums[i]);
    }
};

77. Combinations

题目描述: 给一个n 和一个 k,用这n个数里面,挑k个数组成一个集合,返回所有的组合。

解题思路: 递归得去进行组合,先挑一个,再从剩下的n-1个数里挑k-1个,最后合并一下,解决。

AC代码:

# python
class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        return select_num(k,1,n);
    }   
    vector<vector<int>> select_num(int num,int pos,int n)
    {
        vector<vector<int>> res;
        vector<vector<int>> tmp;
        for (int i = pos ;num > 1 && i <= n ; i ++)
        {
            tmp = select_num(num-1,i+1,n);
            for (int j = 0 ; j < tmp.size() ; j ++)
            {
                tmp[j].insert(tmp[j].begin(),i);
            }
            for (int j = 0 ; j < tmp.size() ; j ++)
                res.push_back(tmp[j]);
        }
        if(num == 1)
        {
            vector<int> tmp2;
            for (int i = pos ;i <= n ; i ++)
            {
                tmp2.push_back(i);
                res.push_back(tmp2);
                tmp2.pop_back();
            }
        }
        return res;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值