[日常刷题]leetcode第十二天

版权声明:希望各位多提意见多多互相交流哦~ https://blog.csdn.net/wait_for_taht_day5/article/details/82809477

121. Best Time to Buy and Sell Stock

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Note that you cannot sell a stock before you buy one.
Example 1:

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
             Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

Solution in C++:

关键点

  • 购入和抛售相对大小

思路

  • 我采取的是暴力的方法,用的冒泡排序的遍历方法,把插值大于0的部分与max进行对比输出。后面也看到了leetcode本身提供的solution中的找极值的算法。思想是min一定是我在prices[i]之前找到的,所以可以直接用来作为减数,得到的最大值即为所求

方法一 暴力

int maxProfit(vector<int>& prices) {
        int max = 0;
        size_t size = prices.size();
        
        for ( int i = 0; i < size; ++i){
            for ( int j = i; j < size; ++j){
                if (prices[i] < prices[j])
                {
                    int tmp = prices[j] - prices[i];
                    max = (max < tmp?tmp:max);
                }
            }
        }
        
        return max;
    }

方法二 遍历一遍,获取后续极小值与极大值

		int min = INT_MAX;
        int max = 0;
        size_t size = prices.size();
        for (int i = 0; i < size; ++i){
            if (prices[i] < min)
                min = prices[i];
            else if (prices[i] - min > max)
                max = prices[i] - min;
        }
        return max;

122. Best Time to Buy and Sell Stock II

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).

Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example 1:

Input: [7,1,5,3,6,4]
Output: 7
Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
             Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.

Example 2:

Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
             Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
             engaging multiple transactions at the same time. You must sell before buying again.

Example 3:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

Solution in C++:
关键点

  • 可以多次抛售,需要顾及前后的影响

思路

  • 相当于三角形问题,两边之和肯定是大于第三边的,所以直接忽略中间点几次的交易肯定是小于进行几次交易的。所以核心点就是我们每次找到相对最小的点和相对大的点进行减法就OK了
int maxProfit(vector<int>& prices) {
        size_t size = prices.size();
        if ( size == 0)
            return 0;
            
        int valley = prices[0];
        int peak = prices[0];
        int max = 0;
        int i = 0;
        
        while (i < size - 1)
        {
            while ( i < size - 1 && prices[i] >= prices[i + 1])
                ++i;
            valley = prices[i];
            while ( i < size - 1 && prices[i] <= prices[i + 1])
                ++i;
            peak = prices[i];
            max += peak - valley;
        }
        return max;
    }

125. Valid Palindrome

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

Note: For the purpose of this problem, we define empty string as valid palindrome.
Example 1:

Input: "A man, a plan, a canal: Panama"
Output: true

Example 2:

Input: "race a car"
Output: false

Solution in C++:
关键点

  • 合法性判断&&前后位置标识移动逻辑

思路

  • 首先是考虑字符串的有效性,然后一头一尾的位置标识遍历字符串,在遍历的过程中如果只有一方的位置标识遇到了非字母及数字的字符就只有该方的位置标识进行挪动,同时判断条件中只返回False的情况,其他运行到最后都是true则返回true
bool isPalindrome(string s) {
        if ( s == "")
            return true;
        
        size_t size = s.size();
        size_t gap = 'a' - 'A';
        for(int i = 0, j = size - 1; i <= j; ++i, --j){
            bool ian = (!isalpha(s[i]) && !isdigit(s[i])); // i为非字母/非数字
            bool jan = (!isalpha(s[j]) && !isdigit(s[j]));
            if (ian && jan)
                continue;
            else if (ian || jan){
                if (ian)
                    ++j;
                else
                    --i;
                continue;
            }
            
            int tmp = abs(s[i] - s[j]);
            if(isalpha(s[i])) // 字母
            {
                if (tmp != gap && tmp != 0)
                    return false;
            } else{
                if (tmp != 0)
                    return false;
            }
        } 
        return true;
    }

小结

今天主要在抛售票的题目中学到了画图去解决问题的思路,以及这种求值大小问题需要考虑一些数学知识。在合法回文中主要学习到的是对于逻辑的正向表达((!isalpha(s[i]) && !isdigit(s[i]))),不要反反的逻辑让自己晕了。

知识点

  • 数学问题
  • 字符处理

猜你喜欢

转载自blog.csdn.net/wait_for_taht_day5/article/details/82809477
今日推荐