验证回文串,两数之和II,移动零问题

本文深入探讨了几个经典的编程问题,包括两数之和的高效求解、移动零的数组操作技巧以及验证回文串的算法实现。通过具体的代码示例,详细讲解了如何利用算法解决实际问题,适合初学者和有经验的开发者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两数之和II

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

示例:输入: numbers = [2, 7, 11, 15], target = 9输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

这里的大致思路并不难想到,我们每从数组拿到一个元素,用目标数减去后得到的值another如果存在于之后的元素里这找到返回下标,但注意,题目给的是一个升序数列,我们可以使用二分查找another,这样会避免在极端情况下(数组极长)程序超时;(如果是无序数组则考虑使用快速排序):

int* twoSum(int* numbers, int numbersSize, int target, int* returnSize)
{
	int another = 0;
	int* tpr = (int*)malloc(sizeof(int) * 2);
	*returnSize = 2;
	int start, end;
	{
		for (int i = 0; i<numbersSize; i++)
		{
			another = target - numbers[i];
			if (another >= numbers[i])
			{
				start = i + 1;
				end = numbersSize - 1;
				while (start<=end)
				{
					int mid = (start + end) / 2;
					if (numbers[mid]==another)
					{
						tpr[0] = i+1;
						tpr[1] = mid+1;
						return tpr;
					}
					else if (numbers[mid]<another)
					{
						start = mid + 1;
					}
					else
					{
						end = mid - 1;
					}
				}
			}
		}
	}
	return tpr;
}
移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:输入: [0,1,0,3,12]输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

我们遍历数组,一旦遇到非0元素,从首元素开始依次覆盖,当遍历完后,我们已经将所有的非零元素放在了数组的前部分,然后把剩下的位置全部赋0即可:

void moveZeroes(int* nums, int numsSize)
{
	int j = 0;
	for (int i = 0; i < numsSize; i++)
	{
		if (nums[i] != 0)
		{
			nums[j++] = nums[i];
		}
	}
	while (j < numsSize)
	{
		nums[j++] = 0;
	}
}
验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:输入: "A man, a plan, a canal: Panama"输出: true
示例 2:输入: "race a car"输出: false

这里我们头尾分别放置两个指针,向中间靠拢,遇到非字母和数字字符时跳过,然后每次两者都抓取到字母和数字字符时比较是否相同即可,这里要注意“0P”字符串,0与P的ASII也相差32:

bool isPalindrome(char* s)
{
	int len = 0;
	while (*(s + len))
	{
		len++;
	}
	char* back = s + len - 1;
	char* start = s;
	while (start<back)
	{
		while ((start<back) && ((*start<'0') || (*start>'9' && *start<'A') || (*start>'Z'&&*start<'a') || (*start>'z')))
		{
			start++;
		}
		while ((start<back) && ((*back<'0') || (*back>'9' && *back<'A') || (*back>'Z'&&*back<'a') || (*back>'z')))
		{
			back--;
		}
		if ((*start != *back)&&(((*start>='0'&&*start<='9')||(*back>='0'&&*back<='9'))||((*start+32 !=*back)&&(*start - 32 != *back))))
		{
			return false;
		}
		start++;
		back--;
	}
	return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值