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;
}
};
题目:
给出两个字符串, 你需要修改第一个字符串,将所有与第二个字符串中相同的字符删除, 并且第二个字符串中不同的字符与第一个字符串的不同字符连接。
样例
思路:
给出 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
, 你不能打劫3
和4
所在的房间,因为它们围成一个圈,是相邻的。
动态规划。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;
}
};