leetcode题解日练--2016.6.23

编程日记,尽量保证每天至少3道leetcode题,仅此记录学习的一些题目答案与思路,尽量用多种思路来分析解决问题,不足之处还望指出。

今日题目:1、从有序数组中删除元素;2、二叉树的层次遍历;3、阶乘后面0的数目;4、杨辉三角II;5、回文数

26. Remove Duplicates from Sorted Array | Difficulty: Easy

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.
题意:给定一个排序好的数组,去掉重复元素,不能利用额外的空间。
思路:
既然已经排好序了,那么就很简单了,从下标为1的元素开始判断,如果当前元素和前面一个元素不想等,就计数一次,同时进行一次赋值操作,若相等则直接访问下一个值
代码:
C++

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n = nums.size();
        if(n<2) return n;
        int res=1;
        for(int i=1;i<nums.size();i++)
        {
            if(nums[i]!=nums[i-1])
                nums[res++] = nums[i];
        }
        return res;
    }
};

结果:32ms

102. Binary Tree Level Order Traversal | Difficulty: Easy

Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).

For example:
Given binary tree [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
return its level order traversal as:
[
[3],
[9,20],
[15,7]
]
题意:从上到下,从左到右遍历一棵树。
与6.21日做的107题基本一致,只是遍历的顺序不同而已。
http://blog.csdn.net/sysu_cis/article/details/51730192
思路:
直接附上代码
c++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> res;

    void DFS(TreeNode*root,int level)
    {
        if(!root) return;
        if(res.size()==level)
            res.push_back(vector<int>());
        res[level].push_back(root->val);
        DFS(root->left,level+1);
        DFS(root->right,level+1);

    }


    vector<vector<int>> levelOrder(TreeNode* root) {

        DFS(root,0);
        return vector<vector<int>>(res.begin(),res.end());
    }
};

结果:8ms
2、BFS写法
第二次刷代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int > >res;
        if(root==NULL)  return res;
        queue<TreeNode*>nodes;
        nodes.push(root);
        while(!nodes.empty())
        {
            int size = nodes.size();
            vector<int>path;
            for(int i=0;i<size;i++)
            {
                TreeNode *cur = nodes.front();
                nodes.pop();
                path.push_back(cur->val);
                if(cur->left)   nodes.push(cur->left);
                if(cur->right)   nodes.push(cur->right);
            }
            res.push_back(path);
        }
        return res;
    }
};

结果:8ms

172. Factorial Trailing Zeroes | Difficulty: Easy

Given an integer n, return the number of trailing zeroes in n!.

Note: Your solution should be in logarithmic time complexity.

题意:给出一个整数n,找到n!最后有几位0。
思路:当a>b的时候,a!后面0的数目一定大于等于b!后面0的数目。那什么时候出现第一个0呢,n=5,第二个0出现在n=10,第三个n=15,那么很显然只有2乘以5才会产生一个10,岁所有数据进行因子的分解,2的数目必定多于5的数目,因此只要计算n!中包含多少个因子5就可以了。
后来想当然的写出计算5个数的式子,发现结果并不对,思考了下发现产生多个5的情况是5的次方,引用https://leetcode.com/discuss/19847/simple-c-c-solution-with-detailed-explaination的例子
Example Three

By given number 4617.

5^1 : 4617 ÷ 5 = 923.4, so we get 923 factors of 5

5^2 : 4617 ÷ 25 = 184.68, so we get 184 additional factors of 5

5^3 : 4617 ÷ 125 = 36.936, so we get 36 additional factors of 5

5^4 : 4617 ÷ 625 = 7.3872, so we get 7 additional factors of 5

5^5 : 4617 ÷ 3125 = 1.47744, so we get 1 more factor of 5

5^6 : 4617 ÷ 15625 = 0.295488, which is less than 1, so stop here.

Then 4617! has 923 + 184 + 36 + 7 + 1 = 1151 trailing zeroes.
代码:
C++

int trailingZeroes(int n) {
    int result = 0;
    for(long long i=5; n/i>0; i*=5){
        result += (n/i);
    }
    return result;
}

结果:7ms

119. Pascal’s Triangle II | Difficulty: Easy

Given an index k, return the kth row of the Pascal’s triangle.

For example, given k = 3,
Return [1,3,3,1].
Note:
Could you optimize your algorithm to use only O(k) extra space?
题意:杨辉三角的一个变形,之前是给出n写出前n行的杨辉三角,现在是给出n写出第n行的杨辉三角。
思路:
首先将杨辉三角这样来看。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
找杨辉三角的规律,首先,两端元素都是1,第0行可以认为既是左边又是右边。
除了两端元素之外的其他每个元素等于它上面一个元素和上面左边元素。i表示行号,j表示列号。
r[i][j] = r[i-1][j-1]+r[i-1][j]
杨辉三角1的代码:

class Solution {
public:
    vector<vector<int> > generate(int numRows) {
        vector<vector<int>> res(numRows);

        for (int i = 0; i < numRows; i++) {
            res[i].resize(i + 1);
            for(int j=0;j<=i;j++)
            {
                if(j==0||j==i)
                    res[i][j] = 1;
                else
                    res[i][j] = res[i-1][j-1]+res[i-1][j];
            }
        }

        return res;
    }
};

结果:4ms
此时,我们当然可以用一样的代码,只不过返回res[rowIndex]而已,但是显然复杂度高了。
因为第i行只与第i-1行有关,所以只需要记录一下前面一行的数据就可以了。这个时候空间复杂度是O(2*k)

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int>cur,pre;
         if(rowIndex<=1)
        {
            while(rowIndex-->=0)
                cur.push_back(1);
            return cur;
        }
        pre.push_back(1);
        pre.push_back(1);
        for(int i=2;i<=rowIndex;i++)
        {
            cur.clear();
            for(int j=0;j<=i;j++)
            {
                if(j==0||j==i)
                    cur.push_back(1);
                else
                    cur.push_back(pre[j-1]+pre[j]);
            }
            pre = cur;

        }
        return cur;
    }
};

结果:3ms

那么还能不能有更低的空间呢?答案是肯定的,但是这需要我们找到每一行的一个通项公式。
但是我没找到,参考了https://leetcode.com/discuss/8364/here-is-my-brief-o-k-solution的solution。

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int> A(rowIndex+1, 0);
        A[0] = 1;
        for(int i=1; i<rowIndex+1; i++)
            for(int j=i; j>=1; j--)
                A[j] += A[j-1];
        return A;
    }
};

暂时马克,说不定哪天突然就明白了。
2016.08.31明白了
第二次刷代码

class Solution {
public:
    vector<int> getRow(int rowIndex) {
        vector<int>res(rowIndex+1,0);
        res[0]=1;
        for(int i=1;i<=rowIndex;i++)
        {
            for(int j=i;j>=0;j--)
                res[j]+=res[j-1];
        }
        return res;
    }
};

结果:2ms

9. Palindrome Number | Difficulty: Easy

Determine whether an integer is a palindrome. Do this without extra space.
题意:判断一个数字是否是回文数
思路:
是整型,因为不允许考虑额外的空间,因此可以将一个数分开两半来看。当数是奇数位的时候,每次原始数字提出最低位作为新数字的最高位,直到新数比原先的数位数多为止。最后判断新数/10和原数是否一样。如果数字是偶数位的情况下,只需要循环到新数大于旧数,如果是回文数字那么终止的时候两个数一定相等,反之不是回文数。

class Solution {
public:
    bool isPalindrome(int x) {

        if(x<0||(x!=0&&x%10==0)) return false;
        int sum = 0;
        while(x>sum)
        {
            sum =sum*10+x%10;
            x /=10;
        }
        return (x==sum)||(sum/10==x);
    }
};

结果:76ms

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值