There are n cities on an axis, numbers from 0 ~ n - 1. John intends to do business in these n cities, He is interested in Armani’s shipment. Each city has a price for these goods prices [i]. For city x, John can buy the goods from the city numbered from x - k to x + k, and sell them to city x. We want to know how much John can earn at most in each city?
注意事項prices.length range is [2, 100000], k <= 100000.
範例
Given prices = [1, 3, 2, 1, 5], k = 2, return [0, 2, 1, 0, 4].
Explanation:i = 0, John can go to the city 0 ~ 2. He can not make money because the prices in city 1 and city 2 are both higher than the price in city 0, that is, ans[0] = 0;i = 1, John can go to the city 0~3. He can buy from city 0 or city 3 to earn the largest price difference. That is, ans[1] = 2.i = 2, John can go to the city 0~4. Obviously, he can earn the largest price difference by buying from city 3. That is, ans[2] = 1.i = 3, John can go to the city 1~4. He can not make money cause city 3 has the lowest price. That is, ans[3] = 0.i = 4, John can go to the city 2~4. He can earn the largest price difference by buying from city 3. That is, ans[4] = 4.
Given prices = [1, 1, 1, 1, 1], k = 1, return [0, 0, 0, 0, 0]
Explanation:All cities are the same price, so John can not make money, that is, all ans are 0.
第一次,TLE
#ifndef C751_H#define C751_H#include<iostream>#include<vector>using namespace std;class Solution {public: /** * @param A: The prices [i] * @param k: * @return: The ans array */ vector<int> business(vector<int> &A, int k) { // Write your code here int len = A.size(); vector<int> res(len, 0); int min = INT_MAX; for (auto c : A) { if (min > c) min = c; } if (k >= len) { for (auto &c : A) c -= min; return A; } for (int i = 0; i < len; ++i) { int value = INT_MIN; if (i - k <= 0 && i + k >= len - 1) { value = A[i] - min; } else if (i - k <= 0 && i + k < len - 1) { for (int j = 0; j <= i + k; ++j) { value = maxVal(value, A[i] - A[j]); } } else if (i - k>0 && i + k >= len - 1) { for (int j = i - k; j < len; ++j) { value = maxVal(value, A[i] - A[j]); } } else { for (int j = i - k; j <= i + k; ++j) { value = maxVal(value, A[i] - A[j]); } } res[i] = value; } return res; } int maxVal(int a, int b) { return a>b ? a : b; }};#endif
題目本質上就是求對於位置i,找到區間[i-k,i+k]上的最小值min,將新值取A[i]-min。
可以利用線段樹:
#ifndef C751_H#define C751_H#include<iostream>#include<vector>using namespace std;class SegmentNode{public: int start, end, min; SegmentNode *left, *right; SegmentNode(int start, int end, int min){ this->start = start; this->end = end; this->min; this->left = this->right = NULL; }};class Solution {public: /** * @param A: The prices [i] * @param k: * @return: The ans array */ vector<int> business(vector<int> &A, int k) { // Write your code here int len = A.size(); vector<int> res(len, 0); SegmentNode *root = build(A, 0, len - 1); for (int i = 0; i<len; ++i) { int start = i - k; int end = i + k; //修正區間範圍 if (start < 0) start = 0; if (end >= len) end = len - 1; res[i] = A[i]-query(root, start, end); } return res; } //查詢線段樹在區間[start,end]上的最小值 int query(SegmentNode *root, int start, int end) { if (start > end || !root) return 0; SegmentNode *node = root; if (start == node->start&&end == node->end) return node->min; if (start >= node->right->start) return query(node->right, start, end); else if (end <= node->left->end) return query(node->left, start, end); else { return minVal(query(node->left, start, node->left->end), query(node->right, node->right->start, end)); } } //構建線段樹,節點包含區間內的最小值 SegmentNode *build(vector<int> &A, int start, int end) { if (start > end) return NULL; SegmentNode *node = new SegmentNode(start, end, INT_MAX); if (start == end) node->min = A[start]; else { node->left = build(A, start, (start + end) / 2); node->right = build(A, (start + end) / 2 + 1, end); node->min = minVal(node->left->min, node->right->min); } return node; } int minVal(int a, int b) { return a < b ? a : b; }};#endif