力扣刷题(刷满1000题)

1.给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

算法思想:用两个for循环 然后一个if进行判断。
int *twoSum(int *nums,int numSize,int target,int *returnSize)
{
int *result=NULL;
for(int i=0;i<numSize-1;i++)
for(int j=i+1;j<numSize;j++)
{
if(nums[i]+nums[j]==target)
{
result=(int *)malloc(sizeof(int)2);
result[0]=i;
result[1]=j;
return result;
}
}
}
这里要注意返回的是
twoSum,所以我们必须得重新开辟一个数组,使之可以返回

2.给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

算法:先根据链表中的值求出来这个数的值,然后逆序输出

struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
ListNode *p=l1;
ListNode *q=l2;
ListNode head=(ListNode )malloc(sizeof(ListNode));
head->next=NULL;
int sum1=0;
int sum2=0
int n=0;
while§
{
sum=sum+2

}
while(q)
{
sum2=sum2+2

}
sum=sum1+sum2;
while(sum)
{
n=sum%10;
sum=sum/10;
ListNode r=(ListNode)malloc(sizeof(ListNode));
r->data=n;
r->nex=head->next;
head->next=r;
}
return head;
}

3.3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

从头到为依次扫描
int lengthOfLongestSubstring(char * s) {

int l,r,max;
l=r=max=0;
int len,i;
len=strlen(s);
while(s[r])
{
for(i=l;i<r;i++)
{
if(s[i]==s[r])l=i+1;
}
max=max<(r-l+1)?(r-l+1):max;
r++;
}
return max;}

4.给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

算法思想:把两个合成一个数组
double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size){
int *ret=(int *)malloc(sizeof(nums1Size+nums2Size));
int i=0,j=0,k=0;
int length;
while(i<nums1Size&&j<nums2Size)
{
if(nums1[i]<nums2[j])
{ret[k++]=nums1[i++];}
else{
ret[k++]=nums2[j++];
}
}
while(i<nums1Size)
ret[k++]=nums1[i++];
while(j<nums2Size)
ret[k++]=nums2[j++];

if(k%2==0)

printf(“%d”,(ret[k/2]+ret[k/2+1])/2);
else{
printf(“%d”,ret[k/2]);
}
return 0;
}

5.给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:

输入:s = “cbbd”
输出:“bb”

算法思想:依次遍历寻找,当找到和遍历开始时,判断,若最大则保存,直到遍历完为止。

代码:bool isPalindrome( char * s , int left , int right )//判断是否相等
{
while ( left < right )
{
if ( s[left++] != s[right–] )
{
return false ;
}
}
return true ;
}

char * longestPalindrome(char * s){
int longest = 0, left = 0, right = 0, longest_left = 0, longest_right = 0;
for (left; s[left] != ‘\0’; left++) //两个for循环
{
for(right = left; s[right] != ‘\0’; right++)
{
if(isPalindrome(s, left, right) && longest < right - left + 1)
{
longest = right - left + 1;
longest_left = left;
longest_right = right;
}
}
}
char *ans = malloc (sizeof(char) * (longest+1));
int i = 0;
for(longest_left; longest_left <= longest_right; longest_left++)
{
ans[i++] = s[longest_left];
}
ans[i] = ‘\0’;
return ans;
}

6.给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

class Solution {
public:
vector<vector> threeSum(vector& nums) {
vector<vector> result;
sort(nums.begin(), nums.end());
// 找出a + b + c = 0
// a = nums[i], b = nums[left], c = nums[right]
for (int i = 0; i < nums.size(); i++) {
// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
if (nums[i] > 0) {
return result;
}
// 错误去重方法,将会漏掉-1,-1,2 这种情况
/*
if (nums[i] == nums[i + 1]) {
continue;
}
/
// 正确去重方法
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1;
int right = nums.size() - 1;
while (right > left) {
// 去重复逻辑如果放在这里,0,0,0 的情况,可能直接导致 right<=left 了,从而漏掉了 0,0,0 这种三元组
/

while (right > left && nums[right] == nums[right - 1]) right–;
while (right > left && nums[left] == nums[left + 1]) left++;
*/
if (nums[i] + nums[left] + nums[right] > 0) {
right–;
} else if (nums[i] + nums[left] + nums[right] < 0) {
left++;
} else {
result.push_back(vector{nums[i], nums[left], nums[right]});
// 去重逻辑应该放在找到一个三元组之后
while (right > left && nums[right] == nums[right - 1]) right–;
while (right > left && nums[left] == nums[left + 1]) left++;

                // 找到答案时,双指针同时收缩
                right--;
                left++;
            }
        }

    }
    return result;
}

};

  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热爱技术的小曹

你的鼓励是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值