栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

打卡leetcode第14天

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

打卡leetcode第14天

1.实现strStr(三种解法)

【题目】

实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。

【分析】

法1:暴力解法:

我们可以让字符串 needle 与字符串 haystack 的所有长度为 m 的子串均匹配一次。

为了减少不必要的匹配,我们每次匹配失败即立刻停止当前子串的匹配,对下一个子串继续匹配。如果当前子串匹配成功,我们返回当前子串的开始位置即可。如果所有子串都匹配失败,则返回 −1。

【C】

int strStr(char * haystack, char * needle){
    for(int i=0;i+strlen(needle)<=strlen(haystack);i++){
        bool flag=true;
        for(int j=0;j 

【C++】

枚举原串 ss 中的每个字符作为「发起点」,每次从原串的「发起点」和匹配串的「首位」开始尝试匹配:

    匹配成功:返回本次匹配的原串「发起点」。
    匹配失败:枚举原串的下一个「发起点」,重新尝试匹配。

class Solution {
public:
    int strStr(string s, string p) {
        int n = s.size(), m = p.size();
        for(int i = 0; i <= n - m; i++){
            int j = i, k = 0; 
            while(k < m and s[j] == p[k]){
                j++;
                k++;
            }
            if(k == m) return i;
        }
        return -1;
    }
};

都很慢

法2:直接用strStr()返回第一个符合的位置,再减去第一个长字符串

【C】

int strStr(char * haystack, char * needle){
    if (needle==0)
    return 0;
    int ans=strstr(haystack,needle)-haystack;
    if (ans<0)
    return -1;
    else
    return ans;
}

这种很快 ,比后边kmp算法还快

法3:KMP算法,求next数组,详细解答见代码随想录

【C】

前缀表不减一版本
void getNext(int* next, char* s) {
    //初始化 next
    int j = 0;
    next[0] = j;
    for (int i = 1; i < strlen(s); i++) {	//注意 i 从 1 开始
        //若前后缀不相同
        while (j > 0 && s[i] != s[j]) {
            //则向前回退
            j = next[j - 1];
        }
        //若前后缀相同
        if (s[i] == s[j]) {
            //i 和 j 同时向后移动(i 的增加在 for 循环里)
            j++;
        }
        //将 j(前缀的长度)赋值给 next[i]
        next[i] = j;
    }
}

int strStr(char * haystack, char * needle){
    int len1 = strlen(haystack);
    int len2 = strlen(needle);
    //当 needle 为空字符串时,返回 0
    if (len2 == 0) {
        return 0;
    }

    //构建 next 数组
    int* next = malloc(sizeof(int) * len2);
    getNext(next, needle);
    //next 记录的起始位置为 0,所以这里也从 0 开始
    int j = 0;
    for (int i = 0; i < len1; i++) {	//注意匹配时 i 从 0 开始
        //若不匹配
        while (j > 0 && haystack[i] != needle[j]) {
            //j 退回到之前匹配的位置
            j = next[j - 1];
        }
        //若匹配
        if (haystack[i] == needle[j]) {
            //i 和 j 同时向后移动(i 的增加在 for 循环里)
            j++;
        }
        //当 j 等于 needle 的长度时,说明字符串 haystack 里出现了字符串 needle
        if (j == len2) {
            //返回 needle 字符串出现的第一个位置
            return (i - len2 + 1);
        }
    }
	
    //若未找到则说明不存在,返回 -1
    return -1;
}

 

 2.通过删除字母匹配到字典中的最长单词

【题目】

【分析】快排再比较

int cmp(const void* a, const void* b){
    char* ap = *(char**)a;
    char* bp = *(char**)b;
    if(strlen(ap) != strlen(bp)){
        return strlen(bp) - strlen(ap);
    }
    return strcmp(ap, bp);
}

bool canDelete(char * s, char * d){
    int sLen = strlen(s);
    int dLen = strlen(d);
    int i = 0, j = 0;
    while(i < sLen && j < dLen){
        if(s[i] == d[j]){
            j++;
            if(j == dLen){
                return true;
            }
        }
        i++;
    }
    return false;
}

char * findLongestWord(char * s, char ** dictionary, int dictionarySize){
    qsort(dictionary, dictionarySize, sizeof(char*), cmp);
    int sLen = strlen(s);
    int i, j, flag = 0;
    char* ans = malloc(sizeof(char) * (sLen + 1));
    for(i = 0; i < dictionarySize; i++){
        if(canDelete(s, dictionary[i]) && sLen >= strlen(dictionary[i])){
            strcpy(ans, dictionary[i]);
            flag = 1;
            break;
        }
    }
    if(flag == 0){
        ans = "";
    }
    return ans;
}

3.有序数组的平方

【题目】

【分析】

法1:先算平方再快排

int cmp(const void* a,const void* b){
    return (*(int*)a-*(int*)b);
}
int* sortedSquares(int* nums, int numsSize, int* returnSize){
    
    
    
    int *ans=(int*)malloc(sizeof(int)*numsSize);
    for(int i=0;i 

法2:双指针法

--直接平方再两边双指针--
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    int* ans = malloc(sizeof(int) * numsSize);
    *returnSize = numsSize;
    for (int i = 0, j = numsSize - 1, pos = numsSize - 1; i <= j;) {
        if (nums[i] * nums[i] > nums[j] * nums[j]) {
            ans[pos] = nums[i] * nums[i];
            ++i;
        } else {
            ans[pos] = nums[j] * nums[j];
            --j;
        }
        --pos;
    }
    return ans;
}
--第二种--
int* sortedSquares(int* nums, int numsSize, int* returnSize){
    int *reNums;
    int left = 0,right = numsSize - 1,i = numsSize - 1;//定义左右“指针”分别从最左和最右开始
    reNums = malloc(sizeof(int) * numsSize); //申请动态数组将原来的值计算比较赋值给新的数组即reNums
    for(int j = 0; j < numsSize; j++){  // 遍历整个数组计算各个数的平方值并重新赋值给nums
        nums[j] = pow(nums[j],2);
    }
    while(left <= right){             // 当右边大于等于左边时进入循环
        if(nums[right] >= nums[left]){//最后一次肯定是左边右边遍历到同一个位置所以等于也要判断
            reNums[i] = nums[right--];//右边赋值后像左偏移-1
        }
        else{
            reNums[i] = nums[left++];//左边赋值后向右偏移即+1
        }
        i--;
    }
    *returnSize = numsSize;//返回数组大小和传入的大小一致
    return reNums;
}

4.移动0

【题目】

【分析】

法1:循环遍历法:

void moveZeroes(int* nums, int numsSize){
    
    int j = 0;
    for (int i = 0; i <= numsSize -1; i++) {
        // 第1步:找到非零数放在数组前端
        if (nums[i] != 0) {
            nums[j] = nums[i];
            j++;
        }
    }

    // 第2步:从j开始到数组末端全赋值0(j之前都是非0数)
    while (j <= numsSize-1) {
        nums[j++] = 0;
    }
}

法2:双指针法:参考:https://leetcode-cn.com/problems/move-zeroes/solution/cyu-yan-ti-jie-xun-huan-bian-li-fa-by-ma-3xgu/

void swap(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}

void moveZeroes(int* nums, int numsSize) {
    // 方法二:双指针交换法(i为右指针, j为左指针)
    int j = 0;
    for (int i = 0; i <= numsSize -1; i++) {
        if (nums[i] != 0) {
            swap(&nums[i], &nums[j]); // 交换数组下标索引i和j对应的元素值
            j++;  // 左指针右移1步
        }
    }
}

5.反转字符串

【题目】

【分析】

双指针法:

【C】

void swap(char *a, char *b) {
    char t = *a;
    *a = *b, *b = t;
}

void reverseString(char *s, int sSize) {
    for (int left = 0, right = sSize - 1; left < right; ++left, --right) {
        swap(s + left, s + right);
    }
}

【C++】

reverse()

class Solution {
public:
    void reverseString(vector& s) {
        reverse(s.begin(),s.end());
    }
};

 

 

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/763838.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号