leetcode题解日练--2016.7.22

日练三题,冰冻三尺非一日之寒。

今日题目: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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值