一、排列硬币
暴力“美学”
1+2+3+4+5+6...一直加上去,知道大于n,最后返回ans - 2的值。
class Solution {
public:
int arrangeCoins(int n) {
long ans, sum;
for(ans = 1, sum = 0; sum <= n; ans++){
sum += ans;
}
return ans - 2;
}
};
二分法
利用等差格式 S = (a0+an)/2*n,用二分法进行找到n
class Solution {
public:
int arrangeCoins(int n) {
long low = 1;
long high = n;
while(low < high){
long mid = (high + low + 1) / 2;
if((long)mid * (mid + 1) <= (long)n * 2){
low = mid;
}else{
high = mid - 1;
}
}
return low;
}
};
二、第k个缺失的正整数
二分法
先用二分法找到令这个数组缺k个正数的前一个位置,然后进行自增得到答案,如果没有该位置,说明全部正数都大于k,所以改为第0位开始自减得到答案。
class Solution {
public:
int findK(vector<int>& arr, int k, int index){
int j = arr[index] - index - 1;
int ans = arr[index];
if(j < k){
while(j < k){
ans++;
j++;
}
}else{
while(j >= k){
ans--;
j--;
}
}
return ans;
}
int findKthPositive(vector<int>& arr, int k) {
int n = arr.size();
int low = 0;
int high = n - 1;
int ans = 0;
while(low <= high){
int mid = low + (high - low) / 2;
if(arr[mid] - mid - 1 < k){
ans = mid;
low = mid + 1;
}else{
high = mid - 1;
}
}
return findK(arr, k, ans);
}
};
暴力法就不写了,很简单的
三、无重复字符的最长子串
滑动窗口(应该算是吧)
ans用来记录最长长度,i一直往后走,每次都会判断在str是否存在重复字符,如果有则继续删除前面的字符直到删到与s[i]相同的字符再i++。
class Solution {
public:
bool findIndex(char s, string ss){
bool isAccept = true;
for(int i = 0; i < ss.length(); i++){
if(ss[i] == s)
isAccept = false;
}
return isAccept;
}
int lengthOfLongestSubstring(string s) {
int n = s.length();
int ans = 0;
string str = "";
for (int i = 0; i < n;) {
if (findIndex(s[i], str)) {
str = str + s[i];
if (str.length() > ans)
ans = str.length();
i++;
}
else {
while (1) {
if (str[0] == s[i]) {
str.erase(0, 1);
break;
}
else {
str.erase(0, 1);
}
}
}
}
return ans;
}
};
四 字符串的排列
滑动窗口
因为只有小写字母,所以可以用s1Flag和s2Flag数组来记录字母出现的频率,通过对比两个数组便可以得出答案。
class Solution {
public:
bool checkInclusion(string s1, string s2) {
int s1Flag[26]= {0};
int n = s1.length();
int m = s2.length();
for(int i = 0; i < n; i++){
s1Flag[s1[i] - 'a'] += 1;
}
for(int i = 0; i < m - n + 1; i++){
int s2Flag[26] = {0};
for(int j = i; j < n + i; j++){
s2Flag[s2[j] - 'a'] += 1;
}
bool flag = true;
for(int z = 0; z < 26; z++){
if(s1Flag[z] != s2Flag[z]){
flag = false;
break;
}
}
if(flag)
return true;
}
return false;
}
};