题目1 ID面试题 01.04

给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。

回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。

回文串不一定是字典当中的单词。

示例1:

输入:"tactcoa"

输出:true(排列有"tacocat"、"atcocta",等等)

我的解答:

  1. bool canPermutePalindrome(char* s){
  2.     int num[200]={0};
  3.     int i,flag=0;
  4.     for(i=0;i<strlen(s);i++){
  5.         num[s[i]]++;
  6.     }
  7.     for(i=0;i<200;i++){
  8.         if(num[i]%2!=0){
  9.             flag++;
  10.         }
  11.     }
  12.     if(flag>1){
  13.         return false;
  14.     }
  15.     return true;
  16. }

  

思路跟之前做过的一个回文数类似,不过这里的题目要求的是给出的字母能不能组成回文字符串,而回文字符串想要组成,那么奇数的字母必须要小于等于1个,想到这里之后,再将得到的字母都储存到数组里面,本来数组大小设置的是小写字母26的,但测试用例里面有\,所以我直接扩展成了200,空间换时间,而且最后空间占用也挺少,内存消耗 :6.7 MB, 在所有 C 提交中击败了100.00%的用户

题目2ID697

给定一个非空且只包含非负数的整数数组 nums, 数组的度的定义是指数组里任一元素出现频数的最大值。

你的任务是找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。

示例 1:

输入: [1, 2, 2, 3, 1]

输出: 2

解释:

输入数组的度是2,因为元素1和2的出现频数最大,均为2.

连续子数组里面拥有相同度的有如下所示:

[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]

最短连续子数组[2, 2]的长度为2,所以返回2.

示例 2:

输入: [1,2,2,3,1,4,2]

输出: 6

注意:

nums.length 在1到50,000区间范围内。

nums[i] 是一个在0到49,999范围内的整数。

我的解答:

这个题目分为两步,第一步是求输入数组的度,第二步是求出与输入数组拥有相同大小度的最短连续子数组。因为题目里面告诉我们输入数组的范围是1--50000,数据不是很大,可以考虑使用空间交换时间。因为度是出现频次最高的数字,所以我们只需要知道频次最高的数字的开始和最远处,即起点固定,每次只更新远处即可。

  1. int findShortestSubArray(int* nums, int numsSize){
  2.     int mark[50000]={0},start[50000]={0},end[50000]={0};
  3.     int i,count=0;
  4.     int min=50000;//[1] numsSize=1 nums[0]=1
  5.     for(i=0;i<numsSize;i++){//mark[1]=1,count=1;mark[1]=1;start[1]=0,end[1]=1;
  6.         mark[nums[i]]++;
  7.         if(mark[nums[i]]>count){
  8.             count=mark[nums[i]];
  9.         }
  10.         if(mark[nums[i]]==1){
  11.             start[nums[i]]=i;
  12.             end[nums[i]]=i;
  13.         }else{
  14.             end[nums[i]]=i;
  15.         }
  16.     }
  17.     for(i=0;i<50000;i++){
  18.         if(mark[i]==count){
  19.             if((end[i]-start[i])<min){
  20.                 min=end[i]-start[i];
  21.             }
  22.         }
  23.     }
  24.     min++;
  25.     return min;
  26. }

  

题目3 ID206

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL

输出: 5->4->3->2->1->NULL

进阶:

你可以迭代或递归地反转链表。你能否用两种方法解决这道题? 

我的解答:

在做https://leetcode-cn.com/problems/palindrome-linked-list-lcci/ 回文链表的时候,需要使用到快慢指针和反转链表,所以先去找了一道反转链表的题目来做。思考了好久反转链表的方式,看了b站的视频:https://www.bilibili.com/video/av24376909?from=search&seid=6943227570952146957 顺利理解(虽然是无声的,但是认真看几分钟就能看懂),写出代码一次通过。

  1. /**
  2.  * Definition for singly-linked list.
  3.  * struct ListNode {
  4.  *     int val;
  5.  *     struct ListNode *next;
  6.  * };
  7.  */
  8.  
  9. struct ListNode* reverseList(struct ListNode* head){
  10.     struct ListNode *curr=head,*p=NULL,*q=NULL;
  11.     while(curr){
  12.         p=curr;
  13.         curr=p->next;
  14.         p->next=q;
  15.         q=p;
  16.     }
  17.     curr=p;
  18.     return curr;
  19. }

  

题目4 ID面试题 02.06

编写一个函数,检查输入的链表是否是回文的。

示例 1:

输入: 1->2

输出: false

示例 2:

输入: 1->2->2->1

输出: true

进阶:

你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

我的解答:

此题在上一道反转链表的基础上做的,先使用快慢指针,即快指针一次走两步,慢指针一次走一步,当快指针到终点的时候,慢指针必然在中点,将中点往后的链表反转,然后与输入链表进行比较即可。

  1. /**
  2.  * Definition for singly-linked list.
  3.  * struct ListNode {
  4.  *     int val;
  5.  *     struct ListNode *next;
  6.  * };
  7.  */
  8.  
  9. bool isPalindrome(struct ListNode* head){
  10.     struct ListNode* fir=head,*sec=head,*p=NULL,*q=NULL,*curr=head;
  11.     if(fir==NULL||fir->next==NULL){
  12.         return true;
  13.     }
  14.     while(sec&&sec->next){
  15.         fir=fir->next;
  16.         sec=sec->next->next;
  17.     }
  18.     while(fir){
  19.         p=fir;
  20.         fir=p->next;
  21.         p->next=q;
  22.         q=p;
  23.     }
  24.     fir=q;
  25.     while(curr&&fir){
  26.         if(curr->val!=fir->val){
  27.             return false;
  28.         }
  29.         curr=curr->next;
  30.         fir=fir->next;
  31.     }
  32.     return true;
  33. }

  

执行用时 :4 ms, 在所有 C 提交中击败了100.00%的用户

内存消耗 :10.9 MB, 在所有 C 提交中击败了100.00%的用户

题目5 ID888

爱丽丝和鲍勃有不同大小的糖果棒:A[i] 是爱丽丝拥有的第 i 块糖的大小,B[j] 是鲍勃拥有的第 j 块糖的大小。

因为他们是朋友,所以他们想交换一个糖果棒,这样交换后,他们都有相同的糖果总量。(一个人拥有的糖果总量是他们拥有的糖果棒大小的总和。)

返回一个整数数组 ans,其中 ans[0] 是爱丽丝必须交换的糖果棒的大小,ans[1] 是 Bob 必须交换的糖果棒的大小。

如果有多个答案,你可以返回其中任何一个。保证答案存在。

示例 1:

输入:A = [1,1], B = [2,2]

输出:[1,2]

示例 2:

输入:A = [1,2], B = [2,3]

输出:[1,2]

示例 3:

输入:A = [2], B = [1,3]

输出:[2,3]

示例 4:

输入:A = [1,2,5], B = [2,4]

输出:[5,4]

提示:

1 <= A.length <= 10000

1 <= B.length <= 10000

1 <= A[i] <= 100000

1 <= B[i] <= 100000

保证爱丽丝与鲍勃的糖果总量不同。

答案肯定存在。

我的解答:

求出输入两个数组和的平均值,就是最后要两人要达到的糖果量,然后寻找能达成目的的数组值即可

  1. /**
  2.  * Note: The returned array must be malloced, assume caller calls free().
  3.  */
  4. int* fairCandySwap(int* A, int ASize, int* B, int BSize, int* returnSize){
  5.     int* re=(int*)malloc(sizeof(int)*2);
  6.     int i,j;
  7.     int Asum=0,Bsum=0;
  8.     int ave=0;
  9.     int flag=0;
  10.     for(i=0;i<ASize;i++){
  11.         Asum+=A[i];
  12.     }
  13.     for(i=0;i<BSize;i++){
  14.         Bsum+=B[i];
  15.     }
  16.     ave=(Asum+Bsum)/2;
  17.     for(i=0;i<ASize;i++){
  18.         for(j=0;j<BSize;j++){
  19.             if(Asum-A[i]+B[j]==ave){
  20.                 re[0]=A[i];
  21.                 re[1]=B[j];
  22.                 flag=1;
  23.                 break;
  24.             }
  25.         }
  26.         if(flag==1){
  27.             break;
  28.         }
  29.     }
  30.     *returnSize=2;
  31.     return re;
  32. }

  

题目6 ID409

给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。

在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。

注意:

假设字符串的长度不会超过 1010。

示例 1:

输入:

"abccccdd"

输出:

7

解释:

我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。

我的解答:

常规思路,存储每个字母出现的次数,偶数的话直接加到length里面,奇数的话需要判断是第一次出现还是二次以上出现,写出代码即可

  1. int longestPalindrome(char * s){
  2.     int num[200]={0};
  3.     int flag=0;
  4.     int i;
  5.     int length=0;
  6.     for(i=0;i<strlen(s);i++){
  7.         num[s[i]]++;
  8.     }
  9.     for(i=0;i<200;i++){
  10.         if(num[i]%2==0){
  11.             length+=num[i];
  12.         }else{
  13.             if(flag==0){
  14.                 length+=num[i];
  15.                 flag=1;
  16.             }else{
  17.                 length+=num[i]-1;
  18.             }
  19.         }
  20.         
  21.     }
  22.     return length;
  23. }

  

题目7 ID155

设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) -- 将元素 x 推入栈中。

pop() -- 删除栈顶的元素。

top() -- 获取栈顶元素。

getMin() -- 检索栈中的最小元素。

示例:

MinStack minStack = new MinStack();

minStack.push(-2);

minStack.push(0);

minStack.push(-3);

minStack.getMin();   --> 返回 -3.

minStack.pop();

minStack.top();      --> 返回 0.

minStack.getMin();   --> 返回 -2.

我的解答:

题目告诉我们要在常数时间内检索到最小元素的栈,所以我们在将数据存入的时候进行处理,调用getMin()直接输出最小值即可,栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成,这里我们多加一个min[],使用min[]数组来储存每一次存入数据的时候的当前的最小值,需要特殊处理的是第一次存入数据的时候,(代码最开始因为首次压入数据没有处理好而出错)每一次存入数据都需要跟上一次的最小值进行比较,第一次存入的时候没有上一次的最小值,我们手动设定一个大值即可,让第一次的数据被成功存入最小值

  1. typedef struct {
  2.     int data[1000];
  3.     int top;
  4.     int min[1000];
  5. } MinStack;
  6.  
  7. /** initialize your data structure here. */
  8. int flag=0;
  9. MinStack* minStackCreate() {
  10.     MinStack* obj=(MinStack*)malloc(sizeof(MinStack));
  11.     obj->top=-1;
  12.     return obj;
  13. }
  14.  
  15. void minStackPush(MinStack* obj, int x) {
  16.     if(obj->top+1<1000){
  17.         long min;
  18.         if(obj->top==-1){
  19.             min=2147483649;
  20.         }else{
  21.             min=obj->min[obj->top];
  22.         }
  23.         obj->top++;
  24.         obj->data[obj->top]=x;
  25.         if(x<min){
  26.             obj->min[obj->top]=x;
  27.         }else{
  28.             obj->min[obj->top]=min;
  29.         }
  30.     }
  31. }
  32.  
  33. void minStackPop(MinStack* obj) {
  34.     if(obj->top>-1){
  35.         obj->top--;
  36.     }
  37. }
  38.  
  39. int minStackTop(MinStack* obj) {
  40.     if(obj->top>-1){
  41.         return obj->data[obj->top];
  42.     }
  43.     return;
  44. }
  45.  
  46. int minStackGetMin(MinStack* obj) {
  47.     if(obj->top>-1){
  48.         return obj->min[obj->top];
  49.     }
  50.     return;
  51. }
  52.  
  53. void minStackFree(MinStack* obj) {
  54.     free(obj);
  55. }
  56.  
  57. /**
  58.  * Your MinStack struct will be instantiated and called as such:
  59.  * MinStack* obj = minStackCreate();
  60.  * minStackPush(obj, x);
  61.  
  62.  * minStackPop(obj);
  63.  
  64.  * int param_3 = minStackTop(obj);
  65.  
  66.  * int param_4 = minStackGetMin(obj);
  67.  
  68.  * minStackFree(obj);
  69. */

  

题目8 ID217

给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

示例 1:

输入: [1,2,3,1]

输出: true

示例 2:

输入: [1,2,3,4]

输出: false

示例 3:

输入: [1,1,1,3,3,4,3,2,4,2]

输出: true

我的解答:

第一次做的时候用数组模拟哈希表,开2000的数组,1000储存正数,1000储存负数,

  1. bool containsDuplicate(int* nums, int numsSize){
  2.     int num[2000]={0};
  3.     int i;
  4.     for(i=0;i<numsSize;i++){
  5.         if(nums[i]<0){
  6.             num[nums[i]+1000]++;
  7.         }else{
  8.             num[nums[i]]++;
  9.         }
  10.         
  11.     }
  12.     for(i=0;i<2000;i++){
  13.         if(num[i]>1){
  14.             return true;
  15.         }
  16.     }
  17.     return false;
  18. }

  

题目测试数据输入极大[-1200000005,-1200000005],证明空间换时间不可行

换一种方法为:

  1. bool containsDuplicate(int* nums, int numsSize){
  2.     int i,j;
  3.     int temp;
  4.     if(numsSize==1){
  5.         return false;
  6.     }
  7.     for(i=0;i<numsSize;i++){
  8.         temp=nums[i];
  9.         for(j=i+1;j<numsSize;j++){
  10.             if(temp==nums[j]){
  11.                 return true;
  12.             }
  13.         }
  14.     }
  15.     return false;
  16. }

  

输入的数据过多导致时间超出限制,说明要找到两全其美的办法

我们先对输入的数组进行排序,然后比较数组相邻两个值是否相等,使用C语言自带的qsort函数排序。

  1. int cmpfunc(int *a,int *b){
  2.     return(*- *b);
  3. }
  4.  
  5. bool containsDuplicate(int* nums, int numsSize){
  6.     int i;
  7.     if(numsSize==1||numsSize==0){
  8.         return false;
  9.     }
  10.     qsort(nums,numsSize,sizeof(int),cmpfunc);
  11.     for(i=1;i<numsSize;i++){
  12.         if(nums[i]==nums[i-1]){
  13.             return true;
  14.         }
  15.     }
  16.     return false;
  17. }

  

题目9 ID896

如果数组是单调递增或单调递减的,那么它是单调的。

如果对于所有 i <= j,A[i] <= A[j],那么数组 A 是单调递增的。 如果对于所有 i <= j,A[i]> = A[j],那么数组 A 是单调递减的。

当给定的数组 A 是单调数组时返回 true,否则返回 false。

示例 1:

输入:[1,2,2,3]

输出:true

示例 2:

输入:[6,5,4,4]

输出:true

示例 3:

输入:[1,3,2]

输出:false

示例 4:

输入:[1,2,4,5]

输出:true

示例 5:

输入:[1,1,1]

输出:true

提示:

1 <= A.length <= 50000

-100000 <= A[i] <= 100000

我的解答:

最开始的时候分情况进行讨论,也就是递增数列,递减数列,常数数列,列出几种情况通过

  1. bool isMonotonic(int* A, int ASize){
  2.     int i=0;
  3.     int check;
  4.     if(ASize==1){
  5.         return true;
  6.     }
  7.     check=A[ASize-1]-A[0];
  8.     if(check>0){
  9.         for(i=0;i<ASize-1;i++){
  10.             if(A[i]>A[i+1]){
  11.                 return false;
  12.             }
  13.         }
  14.     }else if(check<0){
  15.         for(i=0;i<ASize-1;i++){
  16.             if(A[i]<A[i+1]){
  17.                 return false;
  18.             }
  19.         }
  20.     }else{
  21.         for(i=0;i<ASize-1;i++){
  22.             if(A[i]!=A[i+1]){
  23.                 return false;
  24.             }
  25.         }
  26.     }
  27.     return true;
  28. }

  

学习评论区里面的解法,虽然看上去我们需要讨论的情况很多,但是返回false的情况只是左侧的数字不一直大于等于右侧数字,或者右侧数字不一直大于等于左侧数字的时候(当然特殊的只有一个数的时候还是需要讨论),所以我们可以用两个常数a,b来记录这种规律,感觉不太容易想到,学习思路

  1. bool isMonotonic(int* A, int ASize){
  2.     int i=0;
  3.     int a=0,b=0;
  4.     if(ASize==1){
  5.         return true;
  6.     }
  7.     for(i=0;i<ASize-1;i++){
  8.         if(A[i]>A[i+1]){
  9.             a=1;
  10.         }
  11.         if(A[i]<A[i+1]){
  12.             b=1;
  13.         }
  14.     }
  15.     if(a+b==2){
  16.         return false;
  17.     }else{
  18.         return true;
  19.     }
  20.     
  21. }

  

题目10 ID面试题53 - I

统计一个数字在排序数组中出现的次数。

示例 1:

输入: nums = [5,7,7,8,8,10], target = 8

输出: 2

示例 2:

输入: nums = [5,7,7,8,8,10], target = 6

输出: 0

限制:

0 <= 数组长度 <= 50000

我的解答:

这道题目比较简单,因为是排好序的数组,为了令其找完target之后立刻退出,使用goto语句

执行用时 :8 ms, 在所有 C 提交中击败了100.00%的用户

内存消耗 :8.5 MB, 在所有 C 提交中击败了100.00%的用户

  1. int search(int* nums, int numsSize, int target){
  2.     int length=0,i;
  3.     for(i=0;i<numsSize;i++){
  4.         if(nums[i]==target){
  5.             while(i<numsSize&&nums[i]==target){
  6.                 i++;
  7.                 length++;
  8.             }
  9.             goto end;
  10.         }
  11.     }
  12.     end:return length;
  13. }

  

题目11 ID1005

给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们可以多次选择同一个索引 i。)

以这种方式修改数组后,返回数组可能的最大和。

示例 1:

输入:A = [4,2,3], K = 1

输出:5

解释:选择索引 (1,) ,然后 A 变为 [4,-2,3]。

示例 2:

输入:A = [3,-1,0,2], K = 3

输出:6

解释:选择索引 (1, 2, 2) ,然后 A 变为 [3,1,0,2]。

示例 3:

输入:A = [2,-3,-1,5,-4], K = 2

输出:13

解释:选择索引 (1, 4) ,然后 A 变为 [2,3,-1,5,4]。

提示:

1 <= A.length <= 10000

1 <= K <= 10000

-100 <= A[i] <= 100

我的解答:

常规做法,看了题目之后能想到每次反转的都是那个数组里面的最小值,这样才能让整个数组的和最大,每次遍历循环求最小值及其下标再翻转即可。

  1. int largestSumAfterKNegations(int* A, int ASize, int K){
  2.     int i,j;
  3.     int min,min_x,sum=0;
  4.     for(i=0;i<K;i++){
  5.         min=A[0];
  6.         min_x=0;
  7.         for(j=0;j<ASize;j++){
  8.             if(A[j]<min){
  9.                 min=A[j];
  10.                 min_x=j;
  11.             }
  12.         }
  13.         if(min>0||min<0){
  14.             A[min_x]=-A[min_x];
  15.         }
  16.     }
  17.     for(i=0;i<ASize;i++){
  18.         sum+=A[i];
  19.     }
  20.     return sum;
  21. }

  

题目12 ID492

作为一位web开发者, 懂得怎样去规划一个页面的尺寸是很重要的。 现给定一个具体的矩形页面面积,你的任务是设计一个长度为 L 和宽度为 W 且满足以下要求的矩形的页面。要求:

1. 你设计的矩形页面必须等于给定的目标面积。

2. 宽度 W 不应大于长度 L,换言之,要求 L >= W 。

3. 长度 L 和宽度 W 之间的差距应当尽可能小。

你需要按顺序输出你设计的页面的长度 L 和宽度 W。

示例:

输入: 4

输出: [2, 2]

解释: 目标面积是 4, 所有可能的构造方案有 [1,4], [2,2], [4,1]。

但是根据要求2,[1,4] 不符合要求; 根据要求3,[2,2] 比 [4,1] 更能符合要求. 所以输出长度 L 为 2, 宽度 W 为 2。

说明:

给定的面积不大于 10,000,000 且为正整数。

你设计的页面的长度和宽度必须都是正整数。

我的解答:

从面积的开方处开始递减,寻找能够被整除的数字,最快找到的就是距离最近的。

  1. /**
  2.  * Note: The returned array must be malloced, assume caller calls free().
  3.  */
  4. int* constructRectangle(int area, int* returnSize){
  5.     int left,right,i;
  6.     int* a=(int*)malloc(sizeof(int)*2);
  7.     
  8.     *returnSize=2;
  9.     
  10.     for(i=(int)sqrt(area);i>0;i--){
  11.         if(area%i==0){
  12.             a[0]=area/i;
  13.             a[1]=i;
  14.             return a;
  15.         }
  16.     }
  17.     return;
  18. }

  

题目13 ID551

给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符:

'A' : Absent,缺勤

'L' : Late,迟到

'P' : Present,到场

如果一个学生的出勤记录中不超过一个'A'(缺勤)并且不超过两个连续的'L'(迟到),那么这个学生会被奖赏。

你需要根据这个学生的出勤记录判断他是否会被奖赏。

示例 1:

输入: "PPALLP"

输出: True

示例 2:

输入: "PPALLL"

输出: False

我的解答:

根据题目意思写出相应代码,需要注意的是缺勤是否第一次判断需要放在开始

  1. bool checkRecord(char * s){
  2.     int a=0,b=0,i;
  3.     for(i=0;i<strlen(s);i++){
  4.         if(a==1&&s[i]=='A'){
  5.             return false;
  6.         }
  7.         if(s[i]=='A'){
  8.             a=1;
  9.         }
  10.         if((i+2)<strlen(s)&&s[i]==s[i+1]&&s[i]==s[i+2]&&s[i]=='L'){
  11.             return false;
  12.         }
  13.     }
  14.     return true;
  15. }

  

题目14 ID994

在给定的网格中,每个单元格可以有以下三个值之一:

值 0 代表空单元格;

值 1 代表新鲜橘子;

值 2 代表腐烂的橘子。

每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。

返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。

示例 1:

输入:[[2,1,1],[1,1,0],[0,1,1]]

输出:4

示例 2:

输入:[[2,1,1],[0,1,1],[1,0,1]]

输出:-1

解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。

示例 3:

输入:[[0,2]]

输出:0

解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。

提示:

1 <= grid.length <= 10

1 <= grid[0].length <= 10

grid[i][j] 仅为 0、1 或 2

我的解答:

理清楚思路之后其实比较简单,这种做法叫做BFS吗?从每一个腐烂橘子处,检查四个相邻方向是否有新鲜橘子,有的话将其感染为3,因为在本轮感染中,刚被感染的橘子是不能感染其他橘子的,他们需要在下一轮开始的时候才感染其他新鲜橘子。对于检查是否有永远不会被感染的新鲜橘子,我们只需要在腐烂橘子不再增加的时候,循环检测一下是否还有新鲜橘子即可。我们需要做的事情主要是将标记为3的橘子变成2,以及将2的橘子四周的新鲜橘子变为3。

  1. int orangesRotting(int** grid, int gridSize, int* gridColSize){
  2.     int i,j,k;
  3.     int m,n;
  4.     int flag;
  5.     int count=0;
  6.     int num[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
  7.     while(1){
  8.         flag=1;
  9.         for(i=0;i<gridSize;i++){
  10.             for(j=0;j<gridColSize[i];j++){
  11.                 if(grid[i][j]==2){
  12.                     for(k=0;k<4;k++){
  13.                         m=i+num[k][0];
  14.                         n=j+num[k][1];
  15.                         if(m>=0&&n>=0&&m<gridSize&&n<gridColSize[i]&&grid[m][n]==1){
  16.                             grid[m][n]=3;
  17.                             flag=0;
  18.                         }
  19.                     }
  20.                 }
  21.                 
  22.             }
  23.         }
  24.         for(i=0;i<gridSize;i++){
  25.             for(j=0;j<gridColSize[0];j++){
  26.                 if(grid[i][j]==3){
  27.                     grid[i][j]=2;
  28.                 }
  29.             }
  30.         }
  31.         if(flag==1){
  32.             break;
  33.         }else{
  34.             count++;
  35.         }
  36.     }
  37.     for(i=0;i<gridSize;i++){
  38.         for(j=0;j<gridColSize[i];j++){
  39.             if(grid[i][j]==1){
  40.                 return -1;
  41.             }
  42.         }
  43.     }
  44.     return count;
  45.  
  46. }

  

题目15 ID263

编写一个程序判断给定的数是否为丑数。

丑数就是只包含质因数 2, 3, 5 的正整数。

示例 1:

输入: 6

输出: true

解释: 6 = 2 × 3

示例 2:

输入: 8

输出: true

解释: 8 = 2 × 2 × 2

示例 3:

输入: 14

输出: false

解释: 14 不是丑数,因为它包含了另外一个质因数 7。

说明:

1 是丑数。

输入不会超过 32 位有符号整数的范围: [−231,  231 − 1]。

我的解答:

做leetcode做多了之后对于这种没有用到什么数据结构的题目感觉越来越得心应手了,很简单的题目,直接看代码吧。

  1. bool isUgly(int num){
  2.     int flag;
  3.     int test=num;
  4.     if(test==0){
  5.         return false;
  6.     }
  7.     while(test!=1){
  8.         flag=1;
  9.         if(test%2==0){
  10.             test/=2;
  11.             flag=0;
  12.         }
  13.         if(test%3==0){
  14.             test/=3;
  15.             flag=0;
  16.         }
  17.         if(test%5==0){
  18.             test/=5;
  19.             flag=0;
  20.         }
  21.         if(flag){
  22.             break;
  23.         }
  24.     }
  25.     if(flag==1){
  26.         return false;
  27.     }else{
  28.         return true;
  29.     }
  30. }

  

题目16 ID796

给定两个字符串, A 和 B。

A 的旋转操作就是将 A 最左边的字符移动到最右边。 例如, 若 A = 'abcde',在移动一次之后结果就是'bcdea' 。如果在若干次旋转操作之后,A 能变成B,那么返回True。

示例 1:

输入: A = 'abcde', B = 'cdeab'

输出: true

示例 2:

输入: A = 'abcde', B = 'abced'

输出: false

注意:

A 和 B 长度不超过 100。

我的解答:

看到一个python的解法,觉得好强啊,因为A能够经过旋转变成B,那么A+A一定包含有B

  1. class Solution(object):
  2.     def rotateString(self, A, B):
  3.         """
  4.         :type A: str
  5.         :type B: str
  6.         :rtype: bool
  7.         """
  8.         return len(A)==len(B) and B in (A+A)

  

另外是自己用C语言的解法,刚好今天老师讲了约瑟夫生者死者问题,感觉这个题目如果是用C语言的链表构成环形能够做到上面python的效果,如果是使用数组的话,将数组模拟成环形,需要index取余,然后就能进行字符串的比较了。

  1. bool rotateString(char * A, char * B){
  2.     int i,j;
  3.     int length=strlen(A);
  4.     if(strlen(A)!=strlen(B)){
  5.         return false;
  6.     }
  7.     if(strlen(A)==0){
  8.         return true;
  9.     }
  10.     for(i=0;i<length;i++){
  11.         int tmp=i;
  12.         for(j=0;j<length;j++){
  13.             if(A[tmp++]!=B[j]){
  14.                 break;
  15.             }
  16.             tmp%=length;
  17.         }
  18.         if(j==length){
  19.             return true;
  20.         }
  21.     }
  22.     return false;
  23. }

  

题目17 ID83

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

示例 1:

输入: 1->1->2

输出: 1->2

示例 2:

输入: 1->1->2->3->3

输出: 1->2->3

我的解答:

这道题目练习链表的基本操作,因为题目已经给出了是排序链表,所以我们只需要比较相邻两个节点的val是否相同即可,如果相同则删除后一个节点,不同的话则往后继续检查,需要注意的地方是链表的边界操作

  1. /**
  2.  * Definition for singly-linked list.
  3.  * struct ListNode {
  4.  *     int val;
  5.  *     struct ListNode *next;
  6.  * };
  7.  */
  8.  
  9. struct ListNode* deleteDuplicates(struct ListNode* head){
  10.     struct ListNode* test=head;
  11.     while(test!=NULL){
  12.         while(test->next!=NULL&&test->val==test->next->val){
  13.             if(test->next->next==NULL){
  14.                 test->next=NULL;
  15.             }else{
  16.                 test->next=test->next->next;
  17.             }
  18.         }
  19.         test=test->next;
  20.     }
  21.     return head;
  22. }

  

题目18 ID345

编写一个函数,以字符串作为输入,反转该字符串中的元音字母。

示例 1:

输入: "hello"

输出: "holle"

示例 2:

输入: "leetcode"

输出: "leotcede"

说明:

元音字母不包含字母"y"。

我的解答:

元音字母不是只包含aeiou吗?为啥y还要专门提示一下。这道题需要注意的地方是元音字母有大小写之分,然后我们用双指针法,一个从开始,一个从末尾,依次反转即可

  1. bool check(char ch){
  2.     switch(ch){
  3.         case 'A':
  4.         case 'E':
  5.         case 'I':
  6.         case 'O':
  7.         case 'U':
  8.         case 'a':
  9.         case 'e':
  10.         case 'i':
  11.         case 'o':
  12.         case 'u':
  13.             return true;
  14.         default:
  15.             return false;
  16.     }
  17. }
  18. char * reverseVowels(char * s){
  19.     int p,q;
  20.     char* tmp;
  21.     p=0;
  22.     q=strlen(s)-1;
  23.     while(p<q){
  24.         while(!check(s[p])&&p<q){
  25.             p++;
  26.         }
  27.         while(!check(s[q])&&p<q){
  28.             q--;
  29.         }
  30.         tmp=s[p];
  31.         s[p]=s[q];
  32.         s[q]=tmp;
  33.         q--;
  34.         p++;
  35.     }
  36.     return s;
  37. }

  

题目19 ID70

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2

输出: 2

解释: 有两种方法可以爬到楼顶。

1.  1 阶 + 1 阶

2.  2 阶

示例 2:

输入: 3

输出: 3

解释: 有三种方法可以爬到楼顶。

1.  1 阶 + 1 阶 + 1 阶

2.  1 阶 + 2 阶

3.  2 阶 + 1 阶

我的解答:

先使用递归求解,但是递归太消耗时间了,当输入的楼梯数是36的时候就超时了

  1. int climbStairs(int n){
  2.     if(n==0){
  3.         return 0;
  4.     }else if(n==1){
  5.         return 1;
  6.     }else if(n==2){
  7.         return 2;
  8.     }else{
  9.         return climbStairs(n-2)+climbStairs(n-1);
  10.     }
  11.  
  12. }

  

当阶梯数为1,2,3,4时对应的上楼梯方案是1,2,3,5,可以看到当前方案数是前两次之和,所以使用动态规划

  1. int climbStairs(int n){
  2.     if(n==0){
  3.         return 0;
  4.     }else if(n==1){
  5.         return 1;
  6.     }else if(n==2){
  7.         return 2;
  8.     }
  9.     long a=1,b=2;
  10.     int i;
  11.     long tmp;
  12.     for(i=3;i<=n;i++){
  13.         tmp=a+b;
  14.         a=b;
  15.         b=tmp;        
  16.     }
  17.     return tmp;
  18.  
  19. }

  

题目20 ID342

给定一个整数 (32 位有符号整数),请编写一个函数来判断它是否是 4 的幂次方。

示例 1:

输入: 16

输出: true

示例 2:

输入: 5

输出: false

进阶:

你能不使用循环或者递归来完成本题吗?

我的解答:

先用循环来做:

  1. bool isPowerOfFour(int num){
  2.     int tmp=num;
  3.     if(num==0){
  4.         return false;
  5.     }
  6.     while(tmp%4==0){
  7.         tmp/=4;
  8.     }
  9.     if(tmp==1){
  10.         return true;
  11.     }else{
  12.         return false;
  13.     }
  14. }

  

因为题目说不使用循环或者递归来完成,使用数学方法,既然是4的幂次方,那这个数可以写成num=4^n,接着转换成n=log4num,再化简为n=1/2*log2num,因为n一定是一个整数,所以log2num一定是一个偶数,在C语言中按对数换底公式达到这个目的,在一定范围内认为结果是一个整数

  1. #include<math.h>
  2. bool isPowerOfFour(int num){
  3.     if(num==0){
  4.         return false;
  5.     }
  6.     double x = log((double)num) / log(4.0), e = 1e-3;
  7.     int ifloor = floor(x), iceil = ceil(x);
  8.     if (x-ifloor < e || iceil-< e) 
  9.         return true;
  10.     else
  11.         return false;
  12. }

  

题目21 ID205

给定两个字符串 s 和 t,判断它们是否是同构的。

如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。

所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。

示例 1:

输入: s = "egg", t = "add"

输出: true

示例 2:

输入: s = "foo", t = "bar"

输出: false

示例 3:

输入: s = "paper", t = "title"

输出: true

说明:

你可以假设 s 和 t 具有相同的长度。

我的解答:

评论里面有一句话挺好,大概意思是:一个人说法语,另一个人说英语,要想知道他们是不是说的同一个意思,有一个办法就是将他们说的都翻译成中文,看是否相同就行了,在这道题里也是这样,将每一个字母翻译成第一次出现的数字下标,进行比较。

  1. bool isIsomorphic(char * s, char * t){
  2.     int i;
  3.     while(s[i]){
  4.         if(find(s,i)!=find(t,i)){
  5.             return false;
  6.         }
  7.         i++;
  8.     }
  9.     return true;
  10. }
  11. int find(char* ch,int end){
  12.     int i;
  13.     for(i=0;i<=end;i++){
  14.         if(ch[i]==ch[end]){
  15.             return i;
  16.         }
  17.     }
  18.     return end;
  19. }

  

题目22 ID147

对链表进行插入排序。

(好像GIF放进来就动不了了)

插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。

每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。

插入排序算法:

插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。

每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。

重复直到所有输入数据插入完为止。

示例 1:

输入: 4->2->1->3

输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0

输出: -1->0->3->4->5

我的解答:

对链表进行操作,将原链表上面的每一个节点摘取下来,进行比较排序之后放进新链表,最后返回新链表头结点。插入的时候有三种情况,第一种是在头结点之前,第二种是插在中间,第三种是插在末尾,第二种和第三种实际操作是相同的,所以分两种情况进行插入,剩下的就是链表的操作了。

  1. /**
  2.  * Definition for singly-linked list.
  3.  * struct ListNode {
  4.  *     int val;
  5.  *     struct ListNode *next;
  6.  * };
  7.  */
  8.  
  9. struct ListNode* insertionSortList(struct ListNode* head){
  10.     if(head==NULL||head->next==NULL){
  11.         return head;
  12.     }
  13.     struct ListNode* result=NULL;
  14.     struct ListNode* pnew=NULL;
  15.     while(head){
  16.         pnew=head;
  17.         head=head->next;
  18.         pnew->next=NULL;
  19.         //摘取单个节点,将其在新链表上重新排序
  20.         if(result==NULL){
  21.             result=pnew;
  22.         }else{
  23.             struct ListNode* p=result;
  24.             struct ListNode* tmp=p;
  25.             while(p&&p->val<pnew->val){
  26.                 tmp=p;
  27.                 p=p->next;
  28.             }
  29.             //插头结点
  30.             if(p==result){
  31.                 pnew->next=result;
  32.                 result=pnew;
  33.             }else{
  34.                 //插中间或末尾
  35.                 tmp->next=pnew;
  36.                 pnew->next=p;
  37.             }
  38.         }
  39.     }
  40.     return result;
  41. }

  

接着坚持努力吧!

Leetcode学习笔记(2)的更多相关文章

  1. Leetcode学习笔记(4)

    题目1 ID121 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股 ...

  2. Leetcode学习笔记(1)

    scrapy爬虫的学习告一段落,又因为现在在学习数据结构,做题平台是lettcode:https://leetcode-cn.com/ 每周都要交一次做题的笔记,所以把相关代码和思路同时放在博客上记录 ...

  3. leetcode学习笔记--开篇

    1 LeetCode是什么? LeetCode是一个在线的编程测试平台,国内也有类似的Online Judge平台.程序开发人员可以通过在线刷题,提高对于算法和数据结构的理解能力,夯实自己的编程基础. ...

  4. Leetcode学习笔记(5)

    之前断了一段时间没做Leetcode,深感愧疚,重新续上 题目1 ID104 给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点 ...

  5. Leetcode学习笔记(3)

    题目1 ID88 给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量 ...

  6. Leetcode学习笔记(6)

    题目1 ID112 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节点. 示例: 给定如下二叉树,以及目标 ...

  7. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  8. [Java] LinkedList / Queue - 源代码学习笔记

    简单地画了下 LinkedList 的继承关系,如下图.只是画了关注的部分,并不是完整的关系图.本博文涉及的是 Queue, Deque, LinkedList 的源代码阅读笔记.关于 List 接口 ...

  9. 学习笔记之机器学习(Machine Learning)

    机器学习 - 维基百科,自由的百科全书 https://zh.wikipedia.org/wiki/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0 机器学习是人工智能的一个分 ...

随机推荐

  1. 线程安全的SimpleDateFormat

    import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...

  2. Fastdfs集群部署以及基本操作

    FastDFS引言 本地存储与分布式文件系统 本地存储的缺点: 是否有备份? 没有 成本角度? 贵 ​ 服务器 :用于计算 ---- cpu/内存 ​ 用于存储 ---- 硬盘大 存储瓶颈? 容量有限 ...

  3. nagle 算法 tcp nodelay 以及 quick ack分析

    后面详细分析 先上传 之前总结查看源码后的总结 Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段.所谓"小段",指的是小于MSS尺寸的数据块,所谓"未被确 ...

  4. 224、Basic Calculator

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  5. ceph luminous 新功能之内置dashboard

    前言 ceph luminous版本新增加了很多有意思的功能,这个也是一个长期支持版本,所以这些新功能的特性还是很值得期待的,从底层的存储改造,消息方式的改变,以及一些之前未实现的功能的完成,都让ce ...

  6. 建议收藏,从零开始创建一个Activiti工作流,手把手教你完成

    环境配置 项目环境: JDK1.8 tomcat7 maven3.5 开发工具: IDEA activiti7 创建项目 目标:创建一个maven项目,集成Activiti,并自动生成25张数据库表 ...

  7. 大数据和Hadoop平台介绍

    大数据和Hadoop平台介绍 定义 大数据是指其大小和复杂性无法通过现有常用的工具软件,以合理的成本,在可接受的时限内对其进行捕获.管理和处理的数据集.这些困难包括数据的收入.存储.搜索.共享.分析和 ...

  8. [i春秋]“百度杯”CTF比赛 十月场-Hash

    前言 涉及知识点:反序列化.代码执行.命令执行 题目来自:i春秋 hash  如果i春秋题目有问题可以登录榆林学院信息安全协会CTF平台使用 或者利用本文章提供的源码自主复现 [i春秋]"百 ...

  9. Docker这么火爆。章节一:带你详尽了解Docker容器的介绍及使用

    前言 很多小伙伴可能在工作中都听说过Docker,但是实际工作中却没有使用过,听得多了,也对Docker内心有一种很深切的想了解,但是因为各种原因而不知道如何去了解而发愁,不要急,这篇文章带你认识Do ...

  10. L-Rui

    <!DOCTYPE html> <head> <meta charset="UTF-8"> <link rel="shortcu ...