第十五周LeetCode算法题两道

第一道

题目名称:152. Maximum Product Subarray

题目难度:Medium

题目描述:Find the contiguous subarray within an array (containing at least one number) which has the largest product.

For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.

题目分析:
题目要求我们找出乘积最大的相邻子串。子串的长度不定,只要相邻就行。
一开始博主理解错了题目的意思,以为相邻就是最大长度为3,结果秒写出的算法WA了。才发现是任何长度都行。

那么这就是一个动态规划问题了。思路大概是这样的:
从第一位到当前位的最大乘积和前面的数有什么关系呢?即imax[i]与imax[i-1]有什么关系吗?观察可以发现包括当前数字的乘积最大的子串要不就是这个数自己本身组成的子串,要不就是跟之前的将这个数加入前一个数的最长子串之后得到的新的长子串。即imax[i] = max(imax[i-1] * nums[i], nums[i])

思路大概是这样的,但是这道题有一个比较特殊的点,就是nums数组里面可能有负数。如果当前数字是负数的话,他的最大值就要他自己本身以及他乘以他前一位的最小值之间来比较了。所以写程序的时候这一点要留点心。

最后AC的代码是:

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        int imax = nums[0];
        int tMax = 1, tMin = 1;
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] < 0) {
                swap(tMax, tMin);
            }
            tMax = max(nums[i], nums[i] * tMax);
            tMin = min(nums[i], nums[i] * tMin);
            if (tMax > imax) imax = tMax;
        }
        return imax;
    }
};

第二道

题目名称:152. Maximum Product Subarray

题目难度:Medium

题目描述:Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

题目分析:
这道题要求我们找出一个数组中唯一一个只出现了一次的数,其他的数都出现了3次。而且要求算法的时间复杂度应该为O(n),最好不要使用额外的空间。
想了半天想不到比较符合要求的算法。
然后按照自己的思路写了一个时间复杂度为O(nlogn),使用了一个额外空间的算法。
思路很简单,直接使用快排在原地排序,然后按顺序遍历便可以找到这个数了。
最后居然AC了,可能这道题对复杂度的检查没有那么严格。

int singleNumber(vector<int>& nums) {
    if (nums.size() == 1) return nums[0];
    sort(nums.begin(), nums.end());
    for (int i = 0 ;i < nums.size(); ++i) {
      cout << nums[i] << ' ';
    }
    cout << endl;
    for (int i = 0; i < nums.size() - 1; ) {
        if (nums[i] == nums[i+1]) {
            i += 3;
            if (i == nums.size() - 1)
                return nums[i];
        } else {
            return nums[i];
        }
    }
    return 0;
}

完成之后在本题的讨论区看到一个看起来很高级的算法:

public int singleNumber(int[] A) {
    int ones = 0, twos = 0;
    for(int i = 0; i < A.length; i++){
        ones = (ones ^ A[i]) & ~twos;
        twos = (twos ^ A[i]) & ~ones;
    }
    return ones;
}

不过看了半天没怎么理解 = =

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值