由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - candy问题 o(n) time const space 有没有好点的解法。
相关主题
leetcode出新题啦copy constructor 的问题
小孩分candy的狗屁事情直方图下雨这道题怎么解?
请教一个leetcode上的题Cracking上一道题求教
请帖个Median of Two Sorted Arrays的好解法?请问一个java的问题(leetcode subsets一题)
climbing stairs那道题lc 上面4 sum的时间复杂度要求多少?
lc里面那个max points O(n3)的算法也不慢啊问个CONTRACT工作的问题
问个C++的题目C++ Q83: 这个const_cast什么意思?
问道数组元素连续相乘的名题google新题, candy crash
相关话题的讨论汇总
话题: ratings话题: int话题: num话题: sum话题: temp
进入JobHunting版参与讨论
1 (共1页)
h*******e
发帖数: 1377
1
看了几个人的没发现太好的解法,自己的O(n) time const space又有点长46行 大家有
没有
好点的解法。
h*******e
发帖数: 1377
2
discuss 里面有一个, 但是感觉不大好。。
大家上代码的时候尽量 写点小思路,方便他人阅读~~
j*****8
发帖数: 3635
3
我的28行,不过看着也挺繁琐的。思路就是碰到递增的就一直加1,递减的话一直减,
碰到往上走时就回头check一下看那段递减的需不需要调整(负数,或者最小的不是1)
public int candy(int[] ratings) {
if(ratings == null || ratings.length == 0) return 0;
int len = ratings.length;
int[] num = new int[len];
for(int i = 0; i < len; i++) {
if(i == 0) num[i] = 1;
else {
if(ratings[i] > ratings[i-1]) num[i] = num[i-1] + 1;
else if(ratings[i] == ratings[i-1]) num[i] = 1;
else {
num[i] = num[i-1] > 1 ? 1 : num[i-1] - 1;
if(i == len - 1 || ratings[i] <= ratings[i+1])
if(num[i] != 1) adjust(ratings, num, i);
}
}
}
int result = 0;
for(int i = 0; i < len; i++) result += num[i];
return result;
}

private void adjust(int[] ratings, int[] num, int pos) {
int diff = 1 - num[pos];
while(pos >= 1 && ratings[pos] < ratings[pos-1]) {
num[pos] += diff;
pos--;
}
if(num[pos] <= num[pos+1]) num[pos] = num[pos+1] + 1;
}
h*******e
发帖数: 1377
4
楼上做的挺好,只是多用了O(n) 的space, 我也得把我自己的算法帖一下,我的就是
check 上升下降的转折点,然后把 所有单调上升, 单调下降, 单调水平的部分拿出
来 把他们变成最小为一的上升或者下降序列 或者水平序列但是 单调性不变 用等差数
列求和 求部分和, 唯一tricky的地方就是 转折点需要取两边的单调序列的最大值~~~
one pass 不回头查的,空间时间复杂性都不错,但是就是代码太长了, 逻辑也不那
么清晰,还有没有时间空间复杂度类似的,但是思路或者代码比我这个好一些的。减到
了37行现在。
class Solution {
public:
int compare_int(int preVal, int val)
{ return preVal < val ? 1: (preVal > val? -1: 0); }

int candy(vector &ratings) {
int dirVal = 0, preDirVal = -2, preIndex = 0, curIndex, totSum = 0,
preEdge = 1;
for(int rateI = 1; rateI <= ratings.size(); ++ rateI)
{
int val, preVal = ratings[rateI-1];
if(rateI != ratings.size())
{
val = ratings[rateI];
dirVal = compare_int(preVal, val);
}

if(rateI == ratings.size() || preDirVal != -2 && preDirVal !=
dirVal )
{
curIndex = rateI -1;
int size = curIndex - preIndex + 1, newSum = 0;
int frontEdge, backEdge, inc;
if(preDirVal == 1)
{ frontEdge = 1; backEdge = size; inc = 1; }
else if(preDirVal == -1)
{ frontEdge = size; backEdge =1; inc = -1; }
else
{ frontEdge = backEdge = 1; inc = 0; }
totSum += frontEdge * size + size * (size -1 ) /2 * inc +
max(preEdge -frontEdge, 0)
- (rateI != ratings.size()? backEdge: 0);
preEdge = backEdge;
preIndex = curIndex;
}
preDirVal = dirVal;
}
return totSum;
}
};
w**********9
发帖数: 105
5
我这个解法也》30行,
int candy(vector &ratings) {
// Note: The Solution object is instantiated only once and is reused
by each test case.
int sum = ratings.size();
int r=0, l=0, nsum=0;
for (int i=1; i if (ratings[i]>=ratings[i-1]) {
if (l<0) {
sum += -1*(nsum-l);
if (r+l<0) sum += -1*(r+l);
l=0;
nsum = 0;
r= (ratings[i]==ratings[i-1]) ? 0:1;
sum += r;
}
else {
if (ratings[i]>ratings[i-1]) ++r;
else r=0;
sum += r;
}
}
else {
--l;
nsum += l;
}

}
if (l<0) sum += -1*(nsum-l);
if (r+l<0) sum += -1*(r+l);
return sum;
}
h*******e
发帖数: 1377
6
看起来不错能写个简单的思路么。

reused

【在 w**********9 的大作中提到】
: 我这个解法也》30行,
: int candy(vector &ratings) {
: // Note: The Solution object is instantiated only once and is reused
: by each test case.
: int sum = ratings.size();
: int r=0, l=0, nsum=0;
: for (int i=1; i: if (ratings[i]>=ratings[i-1]) {
: if (l<0) {
: sum += -1*(nsum-l);

j*****8
发帖数: 3635
7
嗯,是,那个O(n)的空间应该可以降到O(1),没想这么多。。

~~

【在 h*******e 的大作中提到】
: 楼上做的挺好,只是多用了O(n) 的space, 我也得把我自己的算法帖一下,我的就是
: check 上升下降的转折点,然后把 所有单调上升, 单调下降, 单调水平的部分拿出
: 来 把他们变成最小为一的上升或者下降序列 或者水平序列但是 单调性不变 用等差数
: 列求和 求部分和, 唯一tricky的地方就是 转折点需要取两边的单调序列的最大值~~~
: one pass 不回头查的,空间时间复杂性都不错,但是就是代码太长了, 逻辑也不那
: 么清晰,还有没有时间空间复杂度类似的,但是思路或者代码比我这个好一些的。减到
: 了37行现在。
: class Solution {
: public:
: int compare_int(int preVal, int val)

w**********9
发帖数: 105
8
r 记录前一个连续上升的最高值,l记录连续下降值,负数,如果上升等与或高与下降
(r+l>=0) 就不比调整了。

【在 h*******e 的大作中提到】
: 看起来不错能写个简单的思路么。
:
: reused

h*******e
发帖数: 1377
9
这个似乎很巧妙阿, 好我再仔细看看你的代码。

【在 w**********9 的大作中提到】
: r 记录前一个连续上升的最高值,l记录连续下降值,负数,如果上升等与或高与下降
: (r+l>=0) 就不比调整了。

h*******e
发帖数: 1377
10
恩,你也看看warmspring99的算法么。

【在 j*****8 的大作中提到】
: 嗯,是,那个O(n)的空间应该可以降到O(1),没想这么多。。
:
: ~~

相关主题
lc里面那个max points O(n3)的算法也不慢啊copy constructor 的问题
问个C++的题目直方图下雨这道题怎么解?
问道数组元素连续相乘的名题Cracking上一道题求教
进入JobHunting版参与讨论
x******u
发帖数: 17
11
public class Solution {
public int candy(int[] ratings) {
int num[] = new int[ratings.length];

for (int i = 0; i < ratings.length - 1; i++) {
if (ratings[i+1] > ratings[i]) num[i+1] = num[i] + 1;
}

for (int i = ratings.length - 1; i > 0; i--) {
if (ratings[i-1] > ratings[i]) num[i-1] = Math.max(num[i]+1, num
[i-1]);
}

int sum = 0;
for (int i = 0; i < num.length; i++)
sum += 1 + num[i];
return sum;
}
}
左边扫一遍,右边来一遍
j*****8
发帖数: 3635
12
有个小问题,为啥从零开始分配?题目要求不是至少得要有一个吗?
不过程序是AC了。

【在 h*******e 的大作中提到】
: 恩,你也看看warmspring99的算法么。
h*******e
发帖数: 1377
13
她是求增量,每个元素已经给赋了1了 在sum = ratings.size()的时候。。 再其他的
还没看太清楚~~还在看~~
------------
应该现在明白了

【在 j*****8 的大作中提到】
: 有个小问题,为啥从零开始分配?题目要求不是至少得要有一个吗?
: 不过程序是AC了。

l******e
发帖数: 54
14
20- 行 我的 right 是单调不回溯的 所以是 O(n) 时间,O(1) 空间也显然,程序也应
该显然
class Solution {
public:
int candy(vector& ratings) {
int sum = 0;
int left = -1, right = 1;
for (int i = 0; i < ratings.size(); ++i) {
if (i > 0 && ratings[i] <= ratings[i - 1]) {
left = i - 1;
}
right = max(right, i + 1);
while (right < ratings.size() && ratings[right] < ratings[right - 1]) {
++right;
}
sum += max(i - left, right - i);
}
return sum;
}
};
l******e
发帖数: 54
15
还是解释一下吧
left 表示从 i 开始向左最多能延伸到的点的边界,right 是向右
所以单调区间就是 (left, i] 和 [i, right)
h*******e
发帖数: 1377
16
你的代码一向很好,我明天早上读一下子。

【在 l******e 的大作中提到】
: 20- 行 我的 right 是单调不回溯的 所以是 O(n) 时间,O(1) 空间也显然,程序也应
: 该显然
: class Solution {
: public:
: int candy(vector& ratings) {
: int sum = 0;
: int left = -1, right = 1;
: for (int i = 0; i < ratings.size(); ++i) {
: if (i > 0 && ratings[i] <= ratings[i - 1]) {
: left = i - 1;

j*****8
发帖数: 3635
17
en 那我就明白了。
班上还是有牛人阿,得多交流学习

【在 h*******e 的大作中提到】
: 她是求增量,每个元素已经给赋了1了 在sum = ratings.size()的时候。。 再其他的
: 还没看太清楚~~还在看~~
: ------------
: 应该现在明白了

w**********9
发帖数: 105
18
看着很简洁,我也好好学习一下。

【在 l******e 的大作中提到】
: 20- 行 我的 right 是单调不回溯的 所以是 O(n) 时间,O(1) 空间也显然,程序也应
: 该显然
: class Solution {
: public:
: int candy(vector& ratings) {
: int sum = 0;
: int left = -1, right = 1;
: for (int i = 0; i < ratings.size(); ++i) {
: if (i > 0 && ratings[i] <= ratings[i - 1]) {
: left = i - 1;

p********r
发帖数: 66
19
20 行
public int candySimple(int[] ratings){
if(ratings == null || ratings.length == 0) return 0;
if(ratings.length == 1) return 1;
int[] temp = new int[ratings.length];
temp[0] = 1;
for(int i = 1; i < ratings.length; i++){
if(ratings[i] > ratings[i-1])
temp[i] = temp[i-1] + 1;
else temp[i] = 1;
}
temp[ratings.length - 1] = Math.max(1, temp[ratings.length - 1]);
int last = 1, total = temp[ratings.length - 1];
for(int i = ratings.length - 2; i >= 0 ; i--){
if(ratings[i] > ratings[i+1])
last = last + 1;
else last = 1;
temp[i] = Math.max(temp[i], last);
total += temp[i];
}
return total;
}
h*******e
发帖数: 1377
20
仔细读了,很赞阿!! O(N)时间 O(1)空间。

【在 l******e 的大作中提到】
: 20- 行 我的 right 是单调不回溯的 所以是 O(n) 时间,O(1) 空间也显然,程序也应
: 该显然
: class Solution {
: public:
: int candy(vector& ratings) {
: int sum = 0;
: int left = -1, right = 1;
: for (int i = 0; i < ratings.size(); ++i) {
: if (i > 0 && ratings[i] <= ratings[i - 1]) {
: left = i - 1;

1 (共1页)
进入JobHunting版参与讨论
相关主题
google新题, candy crashclimbing stairs那道题
微软面世经过lc里面那个max points O(n3)的算法也不慢啊
解一道 GOOGLE 面试题 ...问个C++的题目
一点总结,抛砖引玉问道数组元素连续相乘的名题
leetcode出新题啦copy constructor 的问题
小孩分candy的狗屁事情直方图下雨这道题怎么解?
请教一个leetcode上的题Cracking上一道题求教
请帖个Median of Two Sorted Arrays的好解法?请问一个java的问题(leetcode subsets一题)
相关话题的讨论汇总
话题: ratings话题: int话题: num话题: sum话题: temp