lintcode-微软笔试

646. 第一个独特字符位置
题目:
给出一个字符串。找到字符串中第一个不重复的字符然后返回它的下标。如果不存在这样的字符,返回 -1
样例:

给出字符串 s = "lintcode",返回 0
给出字符串 s = "lovelintcode",返回 2

思路:简单的hash应用。遍历一次,纪录每个字符出现的次数,再遍历一次,次数大于1的字符就是答案。

题目链接:http://www.lintcode.com/zh-cn/problem/first-position-unique-character/
代码:
class Solution {
public:
    /*
     * @param s: a string
     * @return: it's index
     */
    int firstUniqChar(string &s) {
        // write your code here
        int len = s.length();
		map <char,int> mp;
        for(int i = 0;i < len; i ++){
        	mp[s[i]] ++; 
        }
        for(int i = 0;i < len ; i ++){
        	if(mp[s[i]] == 1)
        		return i;
        }
        return -1;
    }
};

702. 连接两个字符串中的不同字符 

题目:
给出两个字符串, 你需要修改第一个字符串,将所有与第二个字符串中相同的字符删除, 并且第二个字符串中不同的字符与第一个字符串的不同字符连接。
样例

给出 s1 = aacdb, s2 = gafd
返回 cbgf
给出 s1 = abcs, s2 = cxzca;
返回 bsxz

思路:
遍历字符串s1,把每个出现过的字符标记为1,然后遍历字符串s2中每个字符,如果字符在s1中出现过,标记为-1,其他字符标记为1。最后把标记为1的字符组合成新字符串,即为答案。

题目链接:http://www.lintcode.com/zh-cn/problem/concatenated-string-with-uncommon-characters-of-two-strings/

代码:
class Solution {
public:
    /*
     * @param : the 1st string
     * @param : the 2nd string
     * @return: uncommon characters of given strings
     */
    string concatenetedString(string &s1, string &s2) {
        // write your code here
    	map <char,int> mp;
    	string ans = "";
    	int len1 = s1.length();
    	int len2 = s2.length();
    	if(len2 == 0)
    		return s1;
    	for(int i = 0;i < len1; i ++){
    		if(mp[s1[i]] != 1)
	    		mp[s1[i]] ++;
    	}
    	for(int i = 0;i < len2 ;i ++){
    		if(mp[s2[i]] == 1)
    			mp[s2[i]] = -1;
    	}
    	for(int i = 0;i < len2 ;i ++){
    		if(mp[s2[i]] == -1)
    			continue;
    		if(mp[s2[i]] != 1)
	    		mp[s2[i]] ++;
    	}

    	for(int i = 0;i < len1; i ++){
    		if(mp[s1[i]] == 1){
    			ans = ans + s1[i];
    		}
    	}
    	for(int i = 0;i < len2 ;i ++){
    		if(mp[s2[i]] == 1){
    			ans = ans + s2[i];
    		}
    	}
    	return ans;
    }
};

728. 3个不同的因子

题目:
给一 正整数 n (1 <= n <= 10^18). 判断这个数是否正好只有 3 个不同的因子, 如果正好有 3 个不同的因子就返回 true, 否则返回 false
样例

给出 n = 9, 返回 true 数字 9 正好有 3 个因子: 1, 3, 9, 所以返回 true.
给出 n = 10, 返回 false

思路:
数字 n 只有三个因子,说明除了1和 n 本身,只能有一个因子 x ,且 x 是这个数字的开方。x 除了1和本身不能再有别的因子,因此 x 是质数。首先遍历比1大比 x 小的整数,如果这个整数能整除 n ,即是 n 的因子,返回false。如果找到 x ,判断 x 是否是质数,如果是,返回true ,否则返回false。

题目链接:http://www.lintcode.com/zh-cn/problem/three-distinct-factors/

代码:
class Solution {
public:
    /*
     * @param : the given number
     * @return:  return true if it has exactly three distinct factors, otherwise false
     */
    bool isThreeDisctFactors(long long n) {
        // write your code here
        if(n < 4)
        	return false;
        if(n == 4)
        	return true;
        for(long long i = 3;i * i <= n ;i += 2){
        	if(n % i == 0 && i * i < n){
        		return false;
        	}
        	if(i * i == n){
	        	for(long long j = 2;j*j <= i;j ++){
	        		if(i % j == 0)
	        			return false;
	        	}
	        	return true;
	    	}
        }
        return false;
    }
};


534. 打劫房屋 II
题目:

在上次打劫完一条街道之后,窃贼又发现了一个新的可以打劫的地方,但这次所有的房子围成了一个圈,这就意味着第一间房子和最后一间房子是挨着的。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警

给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,你最多可以得到多少钱 在不触动报警装置的情况下。

样例

给出nums = [3,6,4], 返回 6, 你不能打劫34所在的房间,因为它们围成一个圈,是相邻的。

思路:
动态规划。dp[ i ]表示前 i 个房子能打劫到的最多钱数。动态转移方程:dp1[i] = max(dp1[i-2] + nums[i],dp1[i-1]);(取前一个打劫 和 前一个不打劫的最大钱数)。因为这里是环形,首尾只能打劫一次,设两个状态转移方程,一个是打劫过第一间房屋的,一个是不打劫第一间房屋的,最后取最大值。 

题目链接:http://www.lintcode.com/zh-cn/problem/house-robber-ii/

代码:
class Solution {
public:
    /*
     * @param nums: An array of non-negative integers.
     * @return: The maximum amount of money you can rob tonight
     */
    int houseRobber2(vector<int> nums) {
        // write your code here
        int len = nums.size();
        int dp1[len + 2];
        int dp2[len + 2];
        if(len == 0)
        	return 0;
        if(len == 1)
        	return nums[0];
        dp1[0] = nums[0];
        dp1[1] = max(nums[0],nums[1]);
        dp2[0] = 0;
        dp2[1] = nums[1];
        int ans = dp1[1];
        for(int i = 2; i < len;i ++){
        	dp1[i] = max(dp1[i-2] + nums[i],dp1[i-1]);
        	dp2[i] = max(dp2[i-2] + nums[i],dp2[i-1]);
        	// printf("%d %d\n",dp1[i],dp2[i] );
        	if(i == len - 1){
       			ans = max(ans,dp1[i-1]);
       			ans = max(ans,dp2[i]);
       		}
        }
        return ans;
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值