leetcode题解日练--2016.7.21

日练三题,冰冻三尺非一日之寒。

今日题目:1、三角形;2、超级幂;3、x的n次方。

今日摘录:

To be or not to be,that’s a question.
生存还是毁灭,这是个问题
《哈姆雷特》——莎士比亚

注:补7月21日赶项目落下的题目

120. Triangle | Difficulty: Medium

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

题意:给一个三角形,找到从顶到底和最小的路径,每次只能选择临近的元素。
思路:
1、很直观想到DP来解这个问题。对于每一行元素,去计算它们相应的dp值,每一行元素只会与上一行元素有关,那么可以创建
两个数组,一个数组存放上一行元素,一个数组存放本行元素,直到最后算到最后一行之后得出最小值。
这里需要注意开头和结尾只有一个相邻元素。


class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int cols = triangle.size();
        int res=INT_MAX;
        vector <int> pre (cols+1,INT_MAX);
        vector<int> cur (cols+1,INT_MAX);
        if (cols==0) return 0;
        pre[0] = triangle[0][0];
        for(int i=1;i<triangle.size();i++)
        {
            cur[0]=pre[0]+triangle[i][0];
            for(int j=1;j<i; j++)
            {
                cur[j] = min(pre[j-1],pre[j])+triangle[i][j];
            }
            cur[i] = pre[i-1]+triangle[i][i];
            pre.swap(cur);
        }
        for(auto num:pre)
        {
                if(num<res) res = num;
        }
        return res;
    }
};

结果:8ms

2、其实不同于从上到下去访问,就这道题而言应该采用从下至上的顺序才更加直观。

对于第i层的i个元素,每个元素都有两个相邻元素,即a[i][j] = min(a[i+1][j],a[i+1][j+1])。这么看来好像需要一个另外的元素存下一行的信息?其实不需要,

每次更新第i行第0元素值的时候,需要比较i+1行第0和第1元素,然后更新之后再下一个判断第i行第1元素值的时候,需要比较第i+1行第1元素和第2元素,这个时候即使第0元素被修改了也不会影响最终的结果。


class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        vector<int> res = triangle.back();
        int n = triangle.size();
        for(int layer = n-2;layer>=0;layer--)
        {
            for(int i=0;i<=layer;i++)
            {
                res[i] = min(res[i],res[i+1])+triangle[layer][i];
            }
        }
        return res[0];
    }
};

结果:8ms

372. Super Pow | Difficulty: Medium

Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely large positive integer given in the form of an array.

Example1:

a = 2
b = [3]

Result: 8
Example2:

a = 2
b = [1,0]

Result: 1024
Credits:

tag:Math

题意:数学题,求a的b次方模1337的结果

思路:

1、数学类题目,一般是用到了什么定理之类的,想了会没想出来怎么做

摘自:https://discuss.leetcode.com/topic/50489/c-clean-and-short-solution

fentoyal 的回答:

One knowledge: ab % k = (a%k)(b%k)%k

Since the power here is an array, we’d better handle it digit by digit.
One observation:
a^1234567 % k = (a^1234560 % k) * (a^7 % k) % k = (a^123456 % k)^10 % k * (a^7 % k) % k
Looks complicated? Let me put it other way:
Suppose f(a, b) calculates a^b % k; Then translate above formula to using f :
f(a,1234567) = f(a, 1234560) * f(a, 7) % k = f(f(a, 123456),10) * f(a,7)%k;
Implementation of this idea:

自己重新默写了一遍


class Solution {
public:
    const int base = 1337;
    int DividePow(int a,int k)
    {
        int res=1;
        a %=base;
        for(int i=0;i<k;i++)
        {
            res = (res*a)%base;
        }
        return res;
    }
    int superPow(int a, vector<int>& b) {
        if (b.empty())    return 1;
        int last_bit = b.back();
        b.pop_back();
        return DividePow(superPow(a,b),10) * DividePow(a,last_bit) % base;
    }
};

结果:24ms

50. Pow(x, n) | Difficulty: Medium

Implement pow(x, n).

tag:Math、Binary search

题意:实现x的n次方

思路:

1、试试暴力破解,自己边界情况考虑不周全,7次才通过

class Solution {
public:
    double myPow(double x, int n) {
        double res=1;
        if(x==1 || n==0)    return 1;
        if (x==-1)  return n&1==1? -res:res;
        for(int i=0;i<fabs(n);i++)
        {
            if(n>0 ) res*=x;
            else    res/=x;
            if(res==0)  return 0;
        }
        return res;
    }
};

结果:24ms

2、想到之前遇到的一个比较巧妙的方法

比如我需要求2的10次方,怎么求呢?10=2+8,二进制表示为1010,2的10次方是不是等于2的8次方乘以2的2次方,因此,对于我们需要求n次方,就将n表示成2进制表示,每次n移动一位就将x平方一次,然后每遇到一个数字是1就将其乘进结果。这就是最终所求。
这个可以理解为 x的(1010)B 次方=x的1000次方*x的0010次方,具体怎么体现呢?n有多少位,x就自乘多少次,只有当n当前位是1的时候就乘进结果。

class Solution {
public:
    double myPow(double x, int n) {
       double res=1;
       unsigned long long p;
       if(n<0)
       {
           p = -n;
           x = 1/x;
       }
       else p=n;
       while(p)
       {
           if(p&1)  res*=x;
           x*=x;
           p>>=1;
       }
       return res;
    }
};

结果:6ms

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值