LeetCode中文版网址https://leetcode-cn.com/problemset/all/
最近公司喊口号,要求提高软件能力,并把LeetCode作为技能鉴定的标准,部门也要求每周至少一题LeetCode,加班已经很忙了啊[狗头]
1、拿到题目,首先要分析有哪几种子串类型:
1)aba (以字符为中心对称);
2) abba (以字符间隔为中心对称);
2、分析输入可能的边界条件:
1)输入字符串指针为NULL;
2)输入字符串为“\0”;
3) 输入字符串为 abbbbc,这种情况直接找到b的两端
3、解题思路:
利用回文的对称性,使用指针遍历字符,由该字符向左右两边搜索
函数:
#include
#include
int judge_eq(char* left, char *right)
{
return *left == *right ? 1 : 0;
}
//默认函数输入满足约束
int copy(char* a, char* left, char* right) {
int offset = 0;
if (left == right) {
a[offset++] = *left;
a[offset] = '\0';
return 1;
}
for (char* t = left; t != right + 1; t++) {
a[offset++] = *t;
}
a[offset] = '\0';
return 1;
}
char a[1001];//函数要返回子串,所以只好定义全局变量了
char * longestPalindrome(char * s) {
if (s == NULL)
return s;
if (*s == '\0')//输出空
{
*a = '\0';
printf("%s\n", a);
return a;
}
char *t = s, *right = NULL, *left = NULL;
int offset = 0, ulMaxLength = 0;
while (*t != '\0') {
//判断邻位字符相等
if (*t == *(t + 1)) {
char* temp = t + 1;
while (*temp == *t) {
temp++;
}
left = t;
right = temp - 1; //完全对称
}
else {
left = t; right = t;//左右对称
}
while (left - s >= 0 && *right != '\0')//边界条件
{
if (!judge_eq(left, right))//不相等,跳出循环
break;
if (left == s) {
break;
}
left--;
right++;
}
if (*left == *right && right - left + 1 > ulMaxLength) {
ulMaxLength = right - left + 1;
copy(a, left, right);
}
else if (*left != *right && right - left - 1>ulMaxLength) {
ulMaxLength = right - left - 1;
copy(a, left + 1, right - 1);
}
t++;
}
printf("%s\n", a);
return a;
}
int main() {
char a[1001];
while (gets_s(a)) {
longestPalindrome(a);
}
system("pause");
return 0;
}
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
解题思路:
双指针法 :
1、使用两个指针分别指向数组的两端
2、计算容器的面积,显然容器的深度必须取短板的长度;
3、移动指针,显然移动指针后,容器的宽度会-1,而容器的深度取决于移动后的短板指针。那么可以推测,如果移动当前的长板指针,面积只可能减小;而移动短板指针,面积有一定可能增大,所以移动短板指针。
程序代码如下:
#include
#include
int max(int a, int b) {
return a > b ? a : b;
}
int maxArea(int* height, int heightSize) {
if (heightSize == 0 || height == NULL) {
return 0;
}
int *first = height;
int *end = height + heightSize - 1;
int area_max = 0;
while (first != end) {
int delta_x = end - first;
int delta_y = 0;
if (*first > *end) {
delta_y = *end;
end--;
}
else {
delta_y = *first;
first++;
}
area_max = max(area_max, delta_x*delta_y);
}
return area_max;
}
int main() {
int a[] = { 1,8,6,2,5,4,8,3,7 };
printf("the max water is %d\n", maxArea(a, 9));
getchar();
return 0;
}
给定一个整数 n,返回 n! 结果尾数中零的数量。
示例 1:
输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。
示例 2:
输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.
说明: 你算法的时间复杂度应为 O(log n) 。
#include
#include
#include
//数n!中5以及5的倍数有多少个就好了,
//因为5×2=10,所以产生0的最小因此肯定是2×5,显然0-9的数中5只有一个,那么计算5或5的倍数的个数是最划算的
//例如11!=10!+...5!+...1!
//10!中5的倍数有,10 and 5 数量为2
//5!中5的倍数有5,数量为1
int trailingZeroes(int n){
int count=0;
while(n>=5){
count+=n/5;
n/=5;
}
return count;
}
int main()
{
int n;
scanf("%d",&n);
printf("%d\n",trailingZeroes(n));
return 0;
}
//以下程序未调试
//整数反转
#include
#include
using namespace std;
//负数:-123/10=-12,-123%10=-3,因此程序设计不用区分正负
//[-231,231-1],2^31=2147483648
//10result可能会溢出
#define MAX_31BIT 2147483648 //2^31
#define MAX_32BIT 4294967295
int reverse1(int x){
int result=0;
int a,b;
while(x){
a=x%10;
if(result>(MAX_31BIT-1)/10){
return 0;
}else if(a>MAX_31BIT-1-10result){
return 0;
}
result=10*result+a;
x/=10;
}
return result;
}
int reverse2(int x){
return x;
}
int reverse(int x){
if(x>=0)
return reverse1(x);
else
return reverse2(x);
}
int main(){
int num;
while(scanf("%d",&num)!=EOF){
printf("%d\n",reverse(num));
}
}