日练三题,冰冻三尺非一日之寒。
今日题目:1、摇摆序列;2、区间位与运算;3、有序链表转为BST。
今日摘录:
等待不可怕,可怕的是不知道什么时候是尽头。
——顾漫《何以笙箫默》
376. Wiggle Subsequence | Difficulty: Medium
A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.
For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast,[1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.
Given a sequence of integers, return the length of the longest subsequence that is a wiggle sequence. A subsequence is obtained by deleting some number of elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order.
Examples:
Input: [1,7,4,9,2,5]Output: 6
The entire sequence is a wiggle sequence.Input: [1,17,5,10,13,15,10,5,16,8]Output: 7
There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].Input: [1,2,3,4,5,6,7,8,9]Output: 2
Follow up:
Can you do it in O(n) time?
题意:摇摆子序列,增减增减交替,求这样序列的最大长度。
思路:
1、把问题等价看做求一个函数的极值点的个数,其中首尾均是极值。将数组的下标看做横坐标,数组的值看做纵坐标。基于这个思路去找极值很容易写出代码。
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int res=1,flag = 0;
int n=nums.size();
if (n<2) return n;
for(int i=1;i<n;i++)
{
if(nums[i]>nums[i-1] && (flag==0||flag==-1))
{
res++;
flag=1;
}
else if(nums[i]<nums[i-1] && (flag==0||flag==1))
{
res++;
flag=-1;
}
}
return res;
}
};
结果:0ms
201. Bitwise AND of Numbers Range | Difficulty: Medium
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.
For example, given the range [5, 7], you should return 4.
题意:将区间[m,n]中的所有数字进行按位与操作,返回结果
思路:
1、最蠢的方法就是暴力破解,但是会超时,显然出题者不希望我们这么糊弄过去。稍微想一想有什么巧妙方法呢?可以利用哪些特点?
我们知道2的幂次数都是只有一位1,并且其与上自身-1就为0,一旦为0其他不管来什么数字都是0了。
那么,我们的需要找到的结果就是m和n从高位数起的公共前缀,这样能够保证m和n之间大家都有这个公共前缀,结果也就自然就是这个了。
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
if(m==n||m==0) return m;
int res=0;
while(m!=n)
{
m>>=1;
n>>=1;
res++;
}
return m<<res;
}
};
结果:76ms
109. Convert Sorted List to Binary Search Tree | Difficulty: Medium
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
相关题目:Convert Sorted Array to Binary Search Tree
题意:将排序链表转换为一棵BST。
思路:
1、当时将排序数组转换成BST的时候,是利用了二分查找的思想。但是链表不同于数组,不能直接下标访问。
这个时候,大体思路还是不变,依然是找到中间节点。对于链表找中间结点的方法可以采用一快一慢两个指针的办法。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
return findMidNode(head,NULL);
}
TreeNode* findMidNode(ListNode* head,ListNode* tail)
{
//平凡情况,没有节点
if(head==tail)
return NULL;
//平凡情况,只有一个节点,就新创建一个节点并返回
if (head->next==tail)
{
TreeNode* node = new TreeNode(head->val);
return node;
}
//一般情况
ListNode* fast=head,*slow=head;
while(fast->next!=tail && fast->next->next!=tail)
{
slow = slow->next;
fast = fast->next;
fast = fast->next;
}
TreeNode* mid = new TreeNode (slow->val);
mid->left = findMidNode(head,slow);
mid->right = findMidNode(slow->next,tail);
return mid;
}
};
结果:28ms