关于算法与数据结构的相关博文:
KMP算法相关学习资料
二叉树相关练习题(C++)
经典排序算法的C++实现
与字符串有关的一些典型问题的C++解法
一些可以用动态规划(DP)算法解决的问题(C++)
排列组合相关笔试面试题(C++)
与概率相关的算法题C++解法(附证明过程)
二分查找的巧妙运用(C++)
位运算在算法题中的使用(C++)
链表相关练习题(C++)
用实例讲解栈和队列(C++)
一些智力题的C++解法
一、求字符串的最长无重复字符子串的长度。
解法:动态规划。优化方案为:在查找与当前字符相同的字符位置时,可以用一个循环遍历之前的子串,也可以用hash表直接查找,更省时间。
class
Solution {
public
:
int
lengthOfLongestSubstring(string s) {
int
len = s.size(),start =
0
;
if
(s.empty()||len ==
0
)
vector<
int
> hash(
256
,
-1
);
for
(
int
i =
0
;i < len;i++) {
hash[s[i]] = i;
dp[i+
1
] = max(i-start+
1
,dp[i]);
二、字符串转整数
解法:第一个非空格字符之前的空格忽略;第一个非空格字符是+或-则做相应标记;从第一个非空格字符开始遍历字符串,遇到数字则按规律叠加起来,遇到非数字字符则停止遍历。
class
Solution {
public
:
int
myAtoi(string str) {
int
positive =
1
,i = str.find_first_not_of(' ');
long
sum =
0
;
if
(str[i] == '+' || str[i] == '-')
positive = str[i++] == '-'?-
1
:positive;
while
(isdigit(str[i])) {
sum = (sum<<1) + (sum<<
3
) + str[i++]-'
0
';
if
(sum > INT_MAX)
return
positive ==
1
?INT_MAX:INT_MIN;
}
return
positive*sum;
}
};
三、判断一个整数是不是回文序列
解法:
class
Solution {
public
:
bool
isPalindrome(
int
x) {
if
(x>
0
&& x%
10
==
0
)
return false
;
int
sum =
0
;
while
(sum < x) {
sum = (sum<<
1
)+(sum<<
3
)+x%
10
;
x /=
10
;
}
if
(sum == x||sum/
10
== x)
return true
;
else
return false
;
}
};
四、求两个已排序数组的中位数
解法:二分查找。
①中位数将所有数据分成个数相等的两个部分,且其中一部分全部大于另一部分;
②同时在两个有序数组中查找合适的划分点,由于要保证划分出的两部分数据个数相等,所以只在其中一个数组的下标中进行二分搜索划分点i,从而确定出另外一个数组中的划分点j;
③为了确保由i推导出的j>=0,需选择长度较小的数组进行二分搜索,这样能确保j合法;
④两个划分点左侧的数据为较小的一半,右侧为较大的一半,所以判断搜索出的划分点是否合法的条件为:较小一半的最大值小于较大一半的最小值。否则更新二分搜索的范围。
class
Solution {
public
:
double
findMedianSortedArrays(vector<
int
>& nums1, vector<
int
>& nums2) {
int
len1 = nums1.size(),len2 = nums2.size(),half_len = (len1+len2+
1
)/
2
;
if
(len1 > len2)
return
findMedianSortedArrays(nums2,nums1);
int
start =
0
,end = len1,i,j,numleft,numright;
while
(start <= end) {
i = (start+end)/
2
;
j = half_len-i;
if
(i>0&&j nums2[j])
end = i-1;
else if
(j>0&&i nums1[i])
start = i+1;
else
{
if
(i ==
0
) {
numleft = nums2[j-
1
];
}
else if
(j ==
0
) {
numleft = nums1[i-
1
];
}
else
{
numleft = max(nums1[i-
1
],nums2[j-
1
]);
}
break
;
}
}
if
(j == len2 && len1 !=
0
) numright = nums1[i];
else if
(i == len1 && len2 !=
0
) numright = nums2[j];
else
numright = min(nums1[i],nums2[j]);
return
(len1+len2)%
2
==
1
?(double)numleft:(numleft+numright)/
2.0
;
}
};
五、求字符串的最长回文子串
解法:遍历字符串,以每个字符为中间点向两边扩展比较,记录下最长的回文子串长度和起始位置即可。遇到连续相同的字符要跳过,他们一定包含在同一个回文中。
class
Solution {
public
:
string longestPalindrome(string s) {
int
len = s.size();
if
(len <
2
)
return
s;
int
mid =
0
,maxLen =
1
,start =
0
;
while
(mid < len) {
if
(len-mid <= maxLen/
2
)
break;
int
left = mid,right = mid;
while
(right < len-
1
&& s[right+1] == s[right])
++right;
mid = right+1;
while
(left >
0
&& right < len-
1
&& s[left-
1
] == s[right+
1
]) {
--left;
++right;
}
if
(right-left+
1
> maxLen) {
maxLen = right-left+
1
;
start = left;
}
}
return
s.substr(start,maxLen);
}
};
六、删除链表中某个结点
解法一:循环到链表尾,依次将结点值向前复制一步。
class
Solution {
public
:
void
deleteNode(ListNode* node) {
while
(node->next->next) {
node->val = node->next->val;
node = node->next;
}
node->val = node->next->val;
delete
node->next;
node->next =
NULL
;
}
};
解法二:直接将下一个结点的内容全部复制到当前结点,再删除下一个结点。
class
Solution {
public
:
void
deleteNode(ListNode* node) {
ListNode* next = node->next;
*node = *next;
delete
next;
}
};
七、求小于正整数n的素数个数
class
Solution {
public
:
int
countPrimes(
int
n) {
vector<
int
> hmap(n,
1
);
if
(n <
3
)
return
0
;
int
upper = sqrt(n);
for
(
int
i =
2
;i <= upper;++i) {
if
(hmap[i] ==
0
)
continue
;
for
(
int
non_prime = i*i;non_prime < n;) {
hmap[non_prime] =
0
;
non_prime += i;
}
}
int
count =
0
;
for
(int k =
2
;k < n;++k)
if
(hmap[k] ==
1
)
++count;
return
count;
}
};
八、找到二叉树中所有路径
注意:题中的""不需要输出,""只代表字符串。
解法:递归。
class
Solution {
public
:
void
binaryTreePaths(vector& result, TreeNode* root, string t) {
if
(!root->left && !root->right) {
result.push_back(t);
return
;
}
if
(root->left)
binaryTreePaths(result, root->left, t + "->" + to_string(root->left->val));
if
(root->right)
binaryTreePaths(result, root->right, t + "->" + to_string(root->right->val));
}
vector binaryTreePaths(TreeNode* root) {
vector result;
if
(!root)
return
result;
binaryTreePaths(result, root, to_string(root->val));
return
result;
}
};