So we assume the length of wiggle sequence is equal to the length of input array, and once we meet a redundant difference, (wiggle sequence)--.
To distinguish redundant difference, we need to bring in one boolean variable : positive, which tell us the last number in differences is positive or negative.
One last thing, we deal with the "0" situation, we treat "0" as redundant, and do the same thing.
Here comes the code: (Please let me know if you have better idea or any suggestion, Thx!)
public int wiggleMaxLength(int[] nums) {
if (nums.length <= 1) return nums.length;
int count = nums.length;
Boolean positive = null;
for (int i = 0; i < nums.length-1; i++){
int temp = nums[i+1] - nums[i];
if (temp == 0) count--;
else if (positive == null) positive = temp > 0;
else if ((temp > 0 && positive) || (temp < 0 && !positive))
count--;
else
positive = !positive;
}
return count;
}
list item
class Solution(object):
def wiggleMaxLength(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# trivial case
if (len(nums) < 2):
return len(nums)
# create array of diffs
diffs = []
for i in range(1, len(nums)):
x = nums[i] - nums[i - 1]
# ignore diffs of 0 as they don't count as turning points
if (x != 0):
diffs.append(x)
# if there were diffs of only 0, then seq length is 1
if (not diffs):
return 1
cnt = 1 # min seq length at this stage
# now count the number of times the sign of diff between consecutive numbers changes
# that will be equal to the max wiggle subseq length
for i in range(1, len(diffs)):
prod = diffs[i] * diffs[i - 1]
if (prod < 0):
cnt += 1
return cnt + 1
]]>To see it, first convince yourself that if you have an array with n segments the longest wiggle subsequence cannot have length more than n.
Then convince yourself that if there are n segments, you will always be able to construct a wiggle subsequence of length n.
The code is both the process of counting segments and constructing the wiggle subsequence.
All you need is the last element in the current longest wiggle and if the last segment is increasing.
public int wiggleMaxLength(int[] nums) {
if (nums == null || nums.length == 0) return 0;
int ans = 1, tail = nums[0];
Boolean inc = null;
for (int x: nums) {
if (x == tail) continue;
if (inc == null || inc != x > tail) {
inc = x > tail;
ans++;
}
tail = x;
}
return ans;
}
]]>The main idea is finding how many edges which are different direction next to each others in the this problem.
I initialize the dir with -2, means anywhere.
public class Solution {
public int wiggleMaxLength(int[] nums) {
if(nums.length < 2)return nums.length;
int dir = -2;
int count = 1;
for(int i = 1;i< nums.length;i++){
if(nums[i-1] < nums[i]){
if(dir == 1){continue;}
else {dir = 1; count++; }
}
else if(nums[i-1] > nums[i]){
if(dir == -1){continue;}
else{dir = -1; count++;}
}
}
return count;
}
}
]]>class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size() < 2) return nums.size();
int ans = 1;
int i = 1;
while(i < nums.size() && nums[i] == nums[i-1]) i++;
if(i >= nums.size()) return ans;
bool increase = nums[i] > nums[i-1];
//ans++;
while(i < nums.size()){
if(increase){
while(i+1 < nums.size() && nums[i+1] >= nums[i]) i++;
}
else{
while(i+1 < nums.size() && nums[i+1] <= nums[i]) i++;
}
increase = increase? false : true;
ans++;
i++;
}
return ans;
}
};
]]> public int wiggleMaxLength(int[] nums) {
int size = nums.length;
if(size<=1)return size;
int temp = 1,sign = 0,i = 0;
while(i<size-1){
if(nums[i]>nums[i+1] && (sign==-1 || sign == 0)){
sign=1;
temp++;
}
if(nums[i]<nums[i+1] && (sign==1 || sign == 0)){
sign=-1;
temp++;
}
i++;
}
return temp;
}
]]>start with the second element (i = 1), find the left and right number which is different from current element. If current element is a dip or peak, then it is a turning point.
the first element is a turning point
the last element is a turning point too if it is different from the second last element.
class Solution {
public:
int wiggleMaxLength(vector<int>& nums)
{
int size = nums.size();
if(size<2) return size;
int ans = 1, left, right;
for(int i = 1; i < size; i++ )
{
if(nums[i]==nums[i-1]) continue;
left = right = i;
while(left>0 && nums[--left]==nums[i]){};
while(right<size-1 && nums[++right]==nums[i]){};
if((nums[i]>nums[left] && nums[i]>nums[right])||
(nums[i]<nums[left] && nums[i]<nums[right])) ans++;
}
if(nums[size-2]!=nums[size-1]) ans++;
return ans;
}
};
]]>public int wiggleMaxLength(int[] a) {
if(a.length<2) return a.length;
int prev = a[0], maxLen=1
boolean increasing = a[1]>a[0]; // denoting if we are expecting increased relative to prev
for(int i=1; i<a.length; i++){
if ( (increasing && (a[i] >prev)) || (!increasing && (a[i] < prev) ) ) {
increasing = !increasing;
maxLen++;
}
prev = a[i];
}
return maxLen;
}
]]>public class Solution {
public int wiggleMaxLength(int[] nums) {
if (nums.length <= 1) return nums.length;
int pre_sign = 0;
int signLen = 0;
for (int i = 1; i < nums.length; i++) {
int sign = nums[i] - nums[i-1];
if (sign == 0 || sign * pre_sign > 0) continue;
else {
signLen++;
pre_sign = sign;
}
}
return ++signLen;
}
}
]]> int wiggleMaxLength(vector<int>& nums) {
int count = nums.size() > 0 ? 1 : 0;
int status = 0;
for (int i = 1; i < nums.size(); ++i) {
int newStatus = nums[i] - nums[i-1];
if (status == 0 && newStatus != 0 || newStatus * status < 0) {
status = newStatus;
++count;
}
}
return count;
}
]]>Here is my solution:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size() == 0)
return 0;
vector<int> large(nums.size(),1);
vector<int> small(nums.size(),1);
for(int i=1;i<nums.size();i++){
for(int j=0;j<i;j++){
if(nums[i] > nums[j])
large[i] = max(large[i],small[j]+1);
if(nums[i] < nums[j])
small[i] = max(small[i], large[j]+1);
}
}
return max(*max_element(large.begin(), large.end()), *max_element(small.begin(),small.end()));
}
};
]]>class Solution(object):
def wiggleMaxLength(self, nums):
if not nums:
return 0
seq = [0] + [nums[i+1]-nums[i] for i in range(len(nums)-1)]
count = 1
for i in range(1,len(seq)):
if (seq[i] > 0 and seq[i-1] <= 0) or (seq[i] < 0 and seq[i-1] >= 0):
count += 1
elif seq[i] == 0:
seq[i] = seq[i-1]
return count
]]>