Leetcode(力扣)刷题

目录

  • LeetCode
    • 5. 最长回文子串
    • 11 盛水最多的容器
    • 172.阶乘后的零

LeetCode

LeetCode中文版网址https://leetcode-cn.com/problemset/all/
最近公司喊口号,要求提高软件能力,并把LeetCode作为技能鉴定的标准,部门也要求每周至少一题LeetCode,加班已经很忙了啊[狗头]

5. 最长回文子串

Leetcode(力扣)刷题_第1张图片
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;
}

11 盛水最多的容器

给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
Leetcode(力扣)刷题_第2张图片
图中垂直线代表输入数组 [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;
}

172.阶乘后的零

给定一个整数 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-10
result){
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));
}
}

你可能感兴趣的:(C++)