力扣

力扣之初体验

1.两数之和

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

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

**进阶:**你可以想出一个时间复杂度小于 O(n2) 的算法吗?

题解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int i, j;
for (i = 0; i < numsSize; i++) {
for (j = i + 1; j < numsSize; j++) {
if (nums[i] + nums[j] == target) {
int *arr = (int *) malloc(sizeof(int) * 2);
arr[0] = i;
arr[1] = j;
*returnSize = 2;
return arr;
}
}

}
// 考虑不存在的情况,但本题中不会出现
*returnSize = 0;
return NULL;
}

时间复杂度

这里为暴力循环,第一层先遍历i,然后遍历j当找到相同时创建一个新数组

2.两数相加

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

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

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

示例 1:

img

1
2
3
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

1
2
输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

1
2
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示:

  • 每个链表中的节点数在范围 [1, 100]
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零
题解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode* newNode =NULL;
struct ListNode* head =NULL;
int sum=0,carry=0;//进位
while(l1 || l2)
{
int a= l1 ? l1->val:0;
int b= l2 ? l2->val:0;
sum =a+b+carry;
if(!head)
{
head =newNode =(struct ListNode*)malloc(sizeof(struct ListNode));
newNode ->val=sum%10;
newNode ->next=NULL;
}else
{
newNode ->next=(struct ListNode*)malloc(sizeof(struct ListNode));
newNode->next->val=sum%10;
newNode=newNode->next;
newNode->next=NULL;
}
carry=sum/10;
if(l1)
{
l1=l1->next;
}
if(l2)
{
l2=l2->next;
}
}
if(carry>0)
{
newNode->next =(struct ListNode*)malloc(sizeof(struct ListNode));
newNode->next->val=carry;
newNode= newNode->next;
newNode->next=NULL;
}
return head;
}
3.无重复字符的最长子串

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

示例 1:

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

示例 2:

1
2
3
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

1
2
3
4
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成
题解-滑动窗口解决
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int lengthOfLongestSubstring(char* s) {
int i,len=0,max=0,start=0;
int index[255]={0};
for(i=0;s[i]!='\0';i++)
{
if(index[s[i]]>start)//如果不是第一次出现
{
len=i-start;
start=index[s[i]];
if(len>max)
{
max=len;
}
}
index[s[i]]=i+1;
}
len=strlen(s);
if(len-start>max){
return len-start;
}else
{
return max;
}
}

个人理解:

  1. 首先定义了一个空数组,255个字节代表255的char类型
  2. 进入for循环,这里我们以pwwkew为例
  3. 首先index[s[i]]代表index的第多少元素位置,例如p的阿史克马的位置
  4. p第一次出现,p的位置为0,不大于0,不会进入循环,然后将index[s[0]]的位置改为p的实际位置 1
  5. 同理,w位置为2,此时i为1
  6. w,进入循环,Len =2-0=2;start=2(因为此时未执行到index[s[i]]=i+1;所以start还是上一次的值),max=2;
  7. w时,Len=5-3=3;start=2,max=3