leetcode题解日练--2016.7.6

编程日记,尽量保证每天至少3道leetcode题,仅此记录学习的一些题目答案与思路,尽量用多种思路来分析解决问题,不足之处还望指出。标红题为之后还需要再看的题目。

今日题目:1、不重复字符串最大乘积;2、整型转为罗马数字;3、奇偶链表;4、BST中第k小元素。

318. Maximum Product of Word Lengths | Difficulty: Medium

Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0.

Example 1:
Given [“abcw”, “baz”, “foo”, “bar”, “xtfn”, “abcdef”]
Return 16
The two words can be “abcw”, “xtfn”.

Example 2:
Given [“a”, “ab”, “abc”, “d”, “cd”, “bcd”, “abcd”]
Return 4
The two words can be “ab”, “cd”.

Example 3:
Given [“a”, “aa”, “aaa”, “aaaa”]
Return 0
No such pair of words.
题意:字符串数组中不包含重复字符的字符串中最大长度乘积。
思路:
首先需要知道怎么样表示一个字符串与另一个字符串是否包含相同字母,可以考虑用ont-hot编码,哪个字母出现了,就给那个相应位置1(只区别出现与否,不区别出现次数的差异)。这个时候,两个字符串是否包含相同字母可以通过做一次&操作,如果与操作之后值为0那么就认为这两个元素不包含相同元素。
代码:
C++

class Solution {
public:
    int maxProduct(vector<string>& words) {
    int result=0;
    unordered_map<int,int>  maps;

    for(auto word : words)
    {
        int charset = 0;
        for(auto chr : word)
            charset |=1<<(chr-'a');
        maps[charset] = max(maps[charset],(int)word.size());
        for(auto map:maps)
        {
            if(!(map.first&charset))    
                result = max(result,(int) word.size() * map.second);
        }
    }
    return result;
}
};

结果:135ms

12. Integer to Roman | Difficulty: Medium

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.
题意:将整数转换为罗马数字。
相关题目:罗马数字转整型http://blog.csdn.net/sysu_cis/article/details/51705839
思路:
既然数字范围限定在1-3999之间,那么,我们可以将其拆分为4位,千位为a;百位为b;十位为c;个位为d。现在对于每一位都可以列出相应的转换表,如下:

            个位:{"","I","II","III","IV","V","VI","VII","VIII","IX"},
            十位:{"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
            百位:{"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
            千位:{"","M","MM","MMM"},

有了这个表,我们得到对应位再将其用表转换为对应的罗马数字,然后加起来就可以了。
代码:
C++

class Solution {
public:
    string intToRoman(int num) {
         static const string table[4][10]= 
            { 
                {"","I","II","III","IV","V","VI","VII","VIII","IX"},
                {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
                {"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
                {"","M","MM","MMM"},
            };
        return  table[3][num/1000]+table[2][(num/100)%10]+table[1][(num/10)%10]+table[0][num%10];
    }
};

结果:24ms

328. Odd Even Linked List | Difficulty: Medium

Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.

You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.

Example:
Given 1->2->3->4->5->NULL,
return 1->3->5->2->4->NULL.

Note:
The relative order inside both the even and odd groups should remain as it was in the input.
The first node is considered odd, the second node even and so on …

题意:将链表的奇数位置的元素和偶数位置的元素分别组合在一起.
思路:很直观,模拟一下就能找到变化规律。
递归版本
代码:
C++

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        ListNode* pNode1,*pNode2,*tmp,*head2;
        if(!head||!(head->next))    return head;
        pNode1=head;
        head2 = pNode1->next;
        pNode2 = head2;
        while(pNode1->next&&pNode1->next->next)
        {

            pNode1->next=pNode2->next;
            pNode1 = pNode1->next;
            pNode2->next = pNode1->next;
            pNode2 = pNode2->next;
        }

        pNode1->next = head2;

        return head;
    }
};

结果:20ms

230. Kth Smallest Element in a BST | Difficulty: Medium

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

Note:
You may assume k is always valid, 1 ≤ k ≤ BST’s total elements.

Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

题意:找到一棵BST中第k小的数。
思路:
1、要找第k小的数,首先应该想,有没有什么顺序遍历一棵树直接就是从小到大或者从大到小呢?还真有,那就是中序遍历。因为总是先访问左节点,然后根节点,再右节点,正因为这样的顺序,所以访问到第k个点的时候就是第k小的数。
代码:
C++

/**
 * 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:
    int kthSmallest(TreeNode* root, int k) {
        int res=0,cnt=1;
        stack<TreeNode*>nodes;
        if(!root)   return res;
        TreeNode *cur = root;
        while(cur||!nodes.empty())
        {
            while(cur)
            {
                nodes.push(cur);
                cur = cur->left;
            }
            cur = nodes.top();
            nodes.pop();
            res = cur->val;
            if(cnt==k)  break;
            cur = cur->right;
            cnt++;
        }
        return res;
    }
};

结果:24ms
2、递归版

/**
 * 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:
    int res=0;
    int count=0;
    int kthSmallest(TreeNode* root, int k) {
        count = k;
        helper(root);
        return res;
    }
    void helper(TreeNode* root )
    {
        if(root->left)  helper(root->left);
        count--;
        if(count==0)
        {
            res=root->val;
            return;
        }
        if(root->right) helper(root->right);
    }
};

结果:24ms

3、参考https://discuss.leetcode.com/topic/17810/3-ways-implemented-in-java-binary-search-in-order-iterative-recursive
感觉一种不错的思路,用二分的思想,从根节点开始考虑,首先写一个辅助函数用来计算当前节点作为根节点一共包含的节点数。那么,在根节点无非三种情况:
找的节点在根节点左侧子树,k<=左侧节点数
找的节点在根节点右侧子树,k>左侧节点数+1
找的节点就是根节点,k=左侧节点数+1
对于前面两种情况,再递归去进行就行了。
二分查找

/**
 * 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:

    int kthSmallest(TreeNode* root, int k) {
        int count = countNodes(root->left);
        if(k<=count)    return kthSmallest(root->left,k);
        else if (k>count+1) return kthSmallest(root->right,k-1-count);
        else    return root->val;

    }
    int countNodes(TreeNode* root )
    {
        if(root==NULL)  return 0;
        return 1+countNodes(root->left)+countNodes(root->right);
    }
};

结果:24ms

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值