C语言leetcode(一)

文章目录

    • [C语言][LeetCode][020] Valid Parentheses
    • [C语言][LeetCode][021] Merge Two Sorted Lists
    • [C语言][LeetCode][026] Remove Duplicates from Sorted Array
    • [C语言][LeetCode][027] Remove Element
    • [C语言][LeetCode][028] Implement strStr()
    • [C语言][LeetCode][035] Search Insert Position
    • [C语言][LeetCode][058] Length of Last Word
    • [C语言][LeetCode][083] Remove Duplicates from Sorted List
    • [C语言][LeetCode][088] Merge Sorted Array
    • [C语言][LeetCode][121] Best Time to Buy and Sell Stock
    • [C语言][LeetCode][125] Valid Palindrome
    • [C语言][LeetCode][141] Linked List Cycle
    • [C语言][LeetCode][167] Two Sum II - Input array is sorted

[C语言][LeetCode][020] Valid Parentheses

题目链接:https://leetcode.com/problems/valid-parentheses/description/

题目分析:这是一个括号匹配问题,也是堆栈的经典问题。
这一题需要我们判断输入的字符串括号是否匹配(输入字符串只包含’(’, ‘)’, ‘{’, ‘}’, ‘[’ 和’]’),
例如:若输入字符串是"({})",则返回true(即括号匹配);若输入字符串是"({)}",则返回false(即括号不匹配)。

/*解题思路:这一题代码用到了堆栈中的先进后出概念,
①创建一个标志位flag=-1和一个空字符串stack;
②从第一个字符开始读取输入字符串;
③检查读入的字符,if{如果是’(‘或’{‘或’[’,则标志位加一,同时该括号存入stack;}
else{如果是’)‘或’}‘或’]’,则比较stack最后一次存入的字符,如果相匹配,则标志位减一,否则直接返回false;};
④读取输入字符串的下一个字符,并且每读取一个字符,执行一次步骤③,直至输入字符串全部读取完毕;
⑤最后检查标志位flag是否与初值相等,相等返回true,否则返回false。 */

#include 
#include 
bool isValid(char *s) {
char stack[1000000]; //空字符串stack; 
int flag = -1; //标志位flag; 
while (*s) { //如果字符指针s的内容不为'\0',则执行循环;
if (')' == *s) { //以下三个if任意一个不满足,则括号不匹配,直接返回false; 
if (flag >= 0 && stack[flag--] == '(');
else return false;
}
else if (']' == *s) {
if (flag >= 0 && stack[flag--] == '[');
else return false;
}
else if ('}' == *s) {
if (flag >= 0 && stack[flag--] == '{');
else return false;
}
else {
stack[++flag] = *s;
}
s++; //指针s指向下一个字符空间; 
}
return -1 == flag; //如果标志位flag等于初值(即-1),则说明括号匹配,否则括号不匹配; 
}

int main()
{
char s[] = "{{})";
bool result = isValid(s);
if (result)
printf("括号匹配!\n");
else
printf("括号不匹配!\n");
return 0;
}

[C语言][LeetCode][021] Merge Two Sorted Lists

题目链接:https://leetcode.com/problems/merge-two-sorted-lists/description/

题目意思是输入两组有序链表,要求输出一组新链表,新链表的要求是:链表内的值也是有序的。

/*解题思路:本题主要用到的思路是递归。从输入链表的开始部分值域进行比较大小,
小的链接在新链表末尾,直至两个链表全部比较完毕。 */

#include 
struct ListNode
{
int val;
struct ListNode *next;
};
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
struct ListNode *ret;
if (l1 == NULL) return l2; //如果链表l1是空链表,直接返回链表l2; 
if (l2 == NULL) return l1; //如果链表l2是空链表,直接返回链表l1; 

if (l1->val> l2->val)
{ //比较两组链表最小值域; 
ret = l2; //因为l2值域值更小,所以链接在ret末端; 
ret->next = mergeTwoLists(l1, l2->next); //此处用到了递归; 
return ret;
}
else
{
ret = l1; //因为l1值域值更小,所以链接在ret末端; 
ret->next = mergeTwoLists(l1->next, l2); //此处用到了递归; 
return ret;
}
}

int main()
{
struct ListNode a, b, c, d,e,f,*l1, *l2;
a.val = 1; b.val = 2; c.val = 4;
l1 = &a; a.next = &b; b.next = &c; c.next = NULL;
d.val = 1; e.val = 3; f.val = 4;
l2 = &d; d.next = &e; e.next = &f; f.next = NULL;

struct ListNode result;
result.next = mergeTwoLists(l1,l2);
struct ListNode *p;
p = &result;
while ( p->next != NULL)
{
printf("%d",p->next->val);
p = p->next;
}
//printf("%d", p->val);
return 0;
}

[C语言][LeetCode][026] Remove Duplicates from Sorted Array

题目链接:https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/

题目意思是要求输入一组有序数组,将数组中重复部分删除,也就是说每个数组元素只能出现一次,
最后返回该数组的数组长度。同时,不能创建新的数组变量,必须要在输入的数组中操作。

/** 代码思路:①因为要求不可以创建新数组变量,所以就创建两个int表示数组下标,用来操作输入数组内部元素,
下标分别是 length=0和 i=0;
②从下标0开始比较数组内数字;
③当出现重复数时, i下标向后移动一位,直至与 length下标数字数字不重复;
④此时,将 i位置数字赋到 length位置处, length下标向后移动一位;
⑤重复步骤③,直至数组最后一个数字比完;
⑥最后需要返回的是不重复数组的长度,
因为当前length表示的数组下标,而长度则需要将下标+1, 因此函数返回值是 length+1。 */

#include 
int removeDuplicates(int nums[], int numsSize) {
int i, length = 0; //下标 i和 length; 
if (numsSize <= 1) //如果数组长度小于等于1,直接返回; 
return numsSize;
for (i = 1; i

[C语言][LeetCode][027] Remove Element

题目链接:https://leetcode.com/problems/remove-element/description/

//解:思路和#26相差不大,同样需要两个数组下标,即 length下标和 i下标,其中 i下标是遍历整个数组,而 length下标表示的是“新”数组。
//在 i下标遍历数组过程中,若遇到目标数,下标 i向后移动, length不进行操作;
//若遇到的数不是目标数,则将 i下标数赋给 length下标数,接着 i与 length向后移动,直至 i将数组完整遍历。
//这一题和#26不相同的是,#26的 length是从第二个数字(即 length = 1)开始操作的,而这一题需要从 length = 0开始,
//因为#26的 0下标数字肯定保留(因为 0下标前面没有数字也就不是重复了),
//而这一题 0下标数字是否与目标数相同,需要进行判断,因此从 length = 0开始操作。

#include 
int removeElement(int nums[], int numsSize, int val)
{
int i, len = 0; // i下标和 length下标; 

if (numsSize <= 0)
return numsSize; //如果数组原数组长度非正常值,直接返回; 

for (i = 0; i

[C语言][LeetCode][028] Implement strStr()

题目链接:https://leetcode.com/problems/implement-strstr/description/

题目意思是要求我们在输入字符串haystack[] 中找出第一次出现的子字符串needle[] 是位置。

/*解题思路:首先需要三个整数变量 i, j, temp 来表示字符串下表,其中 i遍历输入字符串haystack[],
temp表示 i下标的haystack[], j是遍历子字符串needle[]。具体如下图所示:
C语言leetcode(一)_第1张图片

最终目标就是比较 haystack[temp]与 needle[j]各位置是否相等,若相等则返回下标 i,即满足条件的下标位置。 */

#include 

int strStr(char haystack[], char needle[]) 
{
int i, j, temp; // 三个下标; 

if (needle[0] == '\0') return 0; // 如果子字符串为空,直接返回0; 

for (i = 0; haystack[i]; i++) 
{ // 用 i遍历haystack[]; 
temp = i; // 将 i赋值给临时变量 temp; 
j = 0; // j=0, 表示了子字符串从头遍历; 

while (needle[j] == haystack[temp] || needle[j] == '\0') 
{ // needle[j]与 haystack[temp]比较; 
if (needle[j] == '\0')
return i; // needle[j] == '\0'说明子字符串比较完成,返回此事下标 i; 
else
j++, temp++;// 即needle[j]还没有全部比完,下表继续向后推; 
}

}

return -1; // 不存在即 needle[]子字符串,因此返回-1; 
}

int main()
{
char haystack[] = "hello";
char needle[] = "llo";
int result = strStr(haystack,needle);

if (result == -1)
printf("不存在输入的子串\n");
else if (result == 0)
printf("输入子串为空\n");
else
{
printf("子串所在的位置为:%d\n",result);
}
return;
}

[C语言][LeetCode][035] Search Insert Position

题目链接:https://leetcode.com/problems/search-insert-position/description/

题目意思是要求给定一个目标数target,将目标数与数组nums[]比较,
根据target的值返回数组nums[]下标值。其中nums[]数组是一组有序数组。

/*解题思路:从nums[0]开始,若target>nums[i],则继续比较后面的nums[],
直至nums[i]<=target,此时返回nums[i]的下标i; */

#include 
int searchInsert(int* nums, int numsSize, int target) 
{
int i;
for (i = 0; i < numsSize; i++)
{
if (target <= nums[i])
{
return i;
}	
}

return numsSize;
}

int main()
{
int nums[] = {1, 2, 3, 5, 6, 9 };
int numsSize = sizeof(nums) / sizeof(nums[0]);
printf("%d\n",numsSize);
int target = 2;
int result = searchInsert(nums,numsSize,target);
printf("%d",result);
return 0;
}

[C语言][LeetCode][058] Length of Last Word

题目链接:https://leetcode.com/problems/length-of-last-word/description/

题目意思是要计算一个字符串中最后一个单词的长度,每隔一个空格即算一个单词。

//解题思路:
//从字符串的最后一个字符开始往前扫描,扫描到空格即跳出,否则计数器加一即可。
//但是我们必须考虑这个字符串的最后几位是空格怎么办的问题,以及这是个空字符串等。
//我第一次提交的时候便没有考虑到字符串最后几位是空格的情况导致出错。引以为戒。
//下面代码中第二个if中与上n即解决了这个问题。

#include 
int lengthOfLastWord(char* s) {
int len = strlen(s);
int n = 0;//计数器,记录最后一个单词的长度
for (int i = len - 1; i >= 0; i--)//从后向前查找
{
if (*(s + i) != ' ')//不是空格则计数
{
n++;
}
else if(*(s+i)== ' ' && n)//检测到空格即跳出
{
break;
}
}
return n;
}

int main()
{
char s[] = " ";
printf("%d\n",lengthOfLastWord(s));
return 0;
}

[C语言][LeetCode][083] Remove Duplicates from Sorted List

题目链接:https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/

//解题思路:用一个临时指针指向list,如果p->val == p->next->val,则将p指针跳过p->next,指向p->next->next。

#include 

struct ListNode
{
int val;
struct ListNode *next;
};
struct ListNode* deleteDuplicates(struct ListNode* head)
{
struct ListNode *p;
p = head;
while (!head)
return NULL;
while (p&&p->next)
{
if (p->val == p->next->val)
{
p->next = p->next->next;
}
else
p = p->next;
}
return head;
}

int main()
{
struct ListNode a, b, c, *head, *p;
a.val = 1;
b.val = 1;
c.val = 2;
a.next = &b;
b.next = &c;
c.next = NULL;
head = &a;
p = deleteDuplicates(head);
do 
{
printf("%d ",p->val);
p = p->next;
} while (p!=NULL);
return 0;
}

[C语言][LeetCode][088] Merge Sorted Array

题目链接:https://leetcode.com/problems/merge-sorted-array/description/

题目意思是给定一个排好序的整型数组nums1、nums2,假定nums1有足够的空间存储,将nums2合并到nums1上,并且是排好序的。

//解题思路:从nums1、nums2的末尾开始比较,将比较的结果放到nums1后面,从后往前放。

#include 
void merge(int* nums1, int m, int* nums2, int n)
{
//int m = a;
//int n = b;

while (m>0 && n>0)
{
if (nums1[m - 1] > nums2[n - 1])
{
nums1[m + n - 1] = nums1[m - 1];
m--;
}
else
{
nums1[m + n - 1] = nums2[n - 1];
n--;
}
}

while (n>0)
{
nums1[m + n - 1] = nums2[n - 1];
n--;
}

while (m>0)
{
nums1[m + n - 1] = nums1[m - 1];
m--;
}
}


//int numsA[6] = { 1,2,3,0,0,0 };
int main()
{
int numsA[6] = { 1,2,3,0,0,0 };
int numsB[3] = {2,5,6};
for (int i = 0; i<6; i++)
{
printf("%d", numsA[i]);
}

int m = 3;
int n = 3;
merge(numsA, m, numsB, n);

for (int i=0;i<6;i++)
{
printf("%d",numsA[i]);
}
return 0;
}

[C语言][LeetCode][121] Best Time to Buy and Sell Stock

题目链接:https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/

//解题思路:直接粗暴的方法,遍历数组中每个元素,找到该元素之后最大的一个元素,算差值,找到差值最大的一个。

#include 

int maxProfit(int* prices, int pricesSize)
{

int max = 0;
for (int i = 0; i < pricesSize; i++)
{
int maxNum = prices[i];
for (int j = i; j < pricesSize; j++)
{
maxNum = prices[j] > maxNum ? prices[j] : maxNum;
}
max = (maxNum - prices[i]) > max ? (maxNum - prices[i]) : max;
}
return max;
}

int main()
{
int prices[] = {7,6,4,3,1};
int pricesSize = 5;
int profit = maxProfit(prices,pricesSize);
printf("%d\n",profit);
return 0;
}

[C语言][LeetCode][125] Valid Palindrome

题目链接:https://leetcode.com/problems/valid-palindrome/description/

//解题思路:在比较两个字符的时候,我们要考虑到大小写的情况,需要将它们转换成同样的大写或者小写样式再来比较。
//我们应该定义两个变量start,length。其中start = 0, length = s.length() - 1。分别表示字符串的两头。
//然后通过循环不断遍历和比较。如果碰到其中start, length同时为合法字符的情况下,但是两者不想等的话,就返回false。
//否则在循环结束后返回true。

#include 
#include 
bool isPalindrome(char* s) {
int length = strlen(s);
int start = 0;
int end = length - 1;
int i;
//将字符串的大写字母转换成小写字母 
for (i = 0; i= 'A' && s[i] <= 'Z')
{
s[i] = s[i] + 32;
}
}

while (start='a')||(s[start]<='9'&&s[start]>='0')))
//	start++;
while (start'z') && (s[start]<'0' || s[start]>'9'))
start++;
//while ((start < end) && !((s[end] <= 'z'&&s[end] >= 'a') || (s[end] <= '9'&&s[end] >= '0')))
//	end--;
//如果不是合法字符,则end往前移动
while (start'z') && (s[end]<'0' || s[end]>'9'))
end--;

//将找到的合法字符进行比较,如果相等,继续看下一对合法字符是否相等,如果不等返回false
if (s[start] == s[end])
{
start++;
end--;
}
else
{
return false;
}
}
return true;
}

int main()
{
char s[] = "race a car";
bool flag = isPalindrome(s);
printf("%d\n",flag);
return 0;
}

[C语言][LeetCode][141] Linked List Cycle

题目链接:https://leetcode.com/problems/linked-list-cycle/description/

//题目意思是判断链表是否会回环。这里的解法是利用快慢指针,快指针每次走两步,慢指针每次走一步,如果快慢指针相遇,说明有回环。

贴一个有意思的漫画,方便大家理解快慢指针:

https://zhuanlan.zhihu.com/p/31401474

#include 
#include 

struct ListNode 
{
int val;
struct ListNode *next;
};

bool hasCycle(struct ListNode *head)
{
struct ListNode *fast, *slow;

fast = head;
slow = head;

while (fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;

if (fast == slow)
return true;
}

return false;
}

int main()
{
struct ListNode a, b, c, d;
a.val = b.val = c.val = d.val = 0;
a.next = &b;
b.next = &c;
c.next = &d;
d.next = NULL;
struct ListNode *head;
head = &a;
bool flag = hasCycle(head);
printf("%d", flag);
return 0;
}

[C语言][LeetCode][167] Two Sum II - Input array is sorted

题目链接:https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/

/**

  • Return an array of size *returnSize.
  • Note: The returned array must be malloced, assume caller calls free().
    /
    /
    *
  • Return an array of size *returnSize.
  • Note: The returned array must be malloced, assume caller calls free().
    */

//题目意思是一个排好序的数组,升序。给你一个数,从数组中找到和为这个数的俩索引,索引不是从0开始的。且只有一组答案

//解题思路:利用两个指针,一个指向头,一个指向末尾,然后比较这两个指针的和与target之间的大小。

#include 
#include 

int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
int i = 0;
int j = numbersSize - 1;
int *a = (int*)malloc(sizeof(int) * 2);
while (i <= j) {
if (numbers[i] + numbers[j] == target) {
a[0] = i + 1;
a[1] = j + 1;
break;
}
if (numbers[i] + numbers[j]>target) {
j--;
}
if (numbers[i] + numbers[j]

你可能感兴趣的:(C语言,leetcode,leetcode)