2024-09-06

题目:给定一个字符串,删除字符串中重复字母,使得每个字母只出现一次。需要保证结果字符串中的字母顺序和原来一致,不改变原来的字母间的相对位置。

解法:

这是一个栈的问题。我们可以使用一个栈来保存我们想要保留的字符,然后遍历整个字符串。当我们遇到一个新的字符时,我们需要确定它是否已经在栈中。如果在,我们就跳过它。如果不在,我们就需要考虑它是否可以放入栈中。当我们遇到一个已存在于栈顶的字符时,我们就需要将栈顶字符移除,直到我们找到一个可以放入的字符或者栈为空。

以下是一个Python的解法:




class Solution:
    def removeDuplicateLetters(self, s: str) -> str:
        stack = []
        letters = [0] * 26
        for char in s:
            letters[ord(char) - ord('a')] += 1
        
        for char in s:
            if char not in stack:
                while stack and char < stack[-1] and letters[ord(stack[-1]) - ord('a')] > 0:
                    stack.pop()
                stack.append(char)
                letters[ord(char) - ord('a')] -= 1
        
        return ''.join(stack)

这个解法的时间复杂度为O(N),空间复杂度为O(N)。

这个解法的核心在于,我们维护了一个字符计数数组,以及一个字符栈。我们遍历字符串中的每一个字符,如果这个字符没有在栈中,我们就将它放入栈中。如果这个字符在栈中已存在,我们就跳过它。当我们遇到一个小于栈顶元素的字符时,我们就需要将栈顶元素移除,直到我们找到一个可以放入的字符或者栈为空。

这个解法保证了字符的相对位置不变,并且只包含每个字符一次。

2024-08-27

题目描述:

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变字符相对顺序的情况下,从字符串中删除某些字符或者不删除的情况。

回文定义为:正读和反读都一样的字符串。

示例 1:

输入:s = "bbbab"

输出:4

解释:一个可能的最长回文子序列为 "bbbb" 。

示例 2:

输入:s = "cbbd"

输出:2

解释:一个可能的最长回文子序列为 "bb" 。

提示:

1 <= s.length <= 1000

s 只包含小写英文字母

解法:

动态规划,使用二维数组 dp 来记录子问题的解。其中 dp[i][j] 表示字符串 s 从 i 到 j 的子串的最长回文子序列的长度。

状态转移方程为:

  • 如果 s[i] == s[j] 且 i 和 j 的下标差值不大于 1(即 i 和 j 是相邻的),那么 dp[i][j] = dp[i+1][j-1] + 2。
  • 如果 s[i] != s[j] 或者 i 和 j 的下标差值大于 1,那么 dp[i][j] = max(dp[i+1][j], dp[i][j-1])。

初始化:

  • 对角线上的元素都初始化为 0,因为 dp[i][i] 总是 1(自身是回文子序列)。
  • 其他位置初始化为 max(0, j - i + 1 - 2),即 j - i + 1 和 0 中的较大值,这是因为如果 i 和 j 之间没有公共字符,那么最长回文子序列长度至少为 j - i + 1。

时间复杂度:O(n^2)




class Solution {
    public int longestPalindromeSubseq(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
 
        for (int i = 0; i < n; i++) {
            dp[i][i] = 1;
        }
 
        for (int len = 2; len <= n; len++) {
            for (int i = 0; i < n - len + 1; i++) {
                int j = i + len - 1;
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                } else {
                    dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
                }
            }
        }
 
        return dp[0][n - 1];
    }
}
2024-08-27

在LeetCode上,有许多关于数组的经典解法问题,以下是一些例子:

    1. 规范数组元素顺序

题目描述:

给定一个非空整数数组,返回其中位数。如果数组中的元素数量是奇数,则返回中位数 middlenum,否则返回两个中位数 middlenum1 和 middlenum2 的平均值。

解法:




public class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int[] nums = new int[nums1.length + nums2.length];
        int index = 0;
        int i = 0, j = 0;
        while (i < nums1.length && j < nums2.length) {
            if (nums1[i] < nums2[j]) {
                nums[index++] = nums1[i++];
            } else {
                nums[index++] = nums2[j++];
            }
        }
        while (i < nums1.length) {
            nums[index++] = nums1[i++];
        }
        while (j < nums2.length) {
            nums[index++] = nums2[j++];
        }
 
        if ((nums.length & 1) == 1) {
            return nums[nums.length / 2];
        } else {
            return (nums[nums.length / 2 - 1] + nums[nums.length / 2]) / 2.0;
        }
    }
}
    1. 移动零

题目描述:

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,非零元素保持原数组顺序。

解法:




public class Solution {
    public void moveZeroes(int[] nums) {
        int j = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != 0) {
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
                j++;
            }
        }
    }
}
    1. 长度最小的子数组

题目描述:

给定一个含有正整数和负整数的数组,找出总和为零的最短非空子数组。

解法:




public class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int ans = Integer.MAX_VALUE;
        int sum = 0;
        int i = 0;
        int j = 0;
        while (i < nums.length) {
            // try to move forward and find a valid subarray
            if (sum < s) {
                sum += nums[i++];
            } else {
                // we have found a valid subarray
                ans = Math.min(ans, i - j);
                sum -= nums[j++];
            }
        }
        return ans == Integer.MAX_VALUE ? 0 : ans;
    }
}

这些例子展示了如何使用数组和一些经典的算法来解决LeetCode上的问题。每个解法都有效率高,易于理解的特点。

2024-08-26



public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}
 
public class Solution {
    // 判断一棵树是否为平衡二叉树
    public boolean isBalanced(TreeNode root) {
        return getHeight(root) != -1;
    }
 
    private int getHeight(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = getHeight(root.left);
        if (leftHeight == -1) {
            return -1;
        }
        int rightHeight = getHeight(root.right);
        if (rightHeight == -1) {
            return -1;
        }
        return Math.abs(leftHeight - rightHeight) > 1 ? -1 : 1 + Math.max(leftHeight, rightHeight);
    }
 
    // 寻找两个节点的最近公共祖先
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) {
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if (left != null && right != null) {
            return root;
        }
        return left != null ? left : right;
    }
}

这段代码首先定义了一个TreeNode类来表示二叉树节点,然后在Solution类中实现了判断平衡二叉树和查找最近公共祖先的方法。isBalanced方法通过计算树的高度来判断是否平衡,如果计算出的高度为-1,则表示不是平衡的。lowestCommonAncestor方法递归地查找两个节点pq的最近公共祖先。如果当前节点是null,或者当前节点是pq之一,则直接返回当前节点。否则,递归查找左右子树,如果左右子树均不为null,则当前节点为最近公共祖先。如果左子树不为null,则返回左子树的结果,否则返回右子树的结果。

2024-08-26



/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root.val < p.val && root.val < q.val) {
            return lowestCommonAncestor(root.right, p, q);
        } else if (root.val > p.val && root.val > q.val) {
            return lowestCommonAncestor(root.left, p, q);
        } else {
            return root;
        }
    }
}

这段代码实现了二叉搜索树中最近公共祖先的查找。它通过递归对树进行遍历,并根据每个节点与目标节点的值比较结果来决定是继续在左子树还是右子树中查找。如果目标节点值都小于当前节点,则在当前节点的左子树中继续查找;如果目标节点值都大于当前节点,则在当前节点的右子树中继续查找;如果找到了两个目标节点值分别位于当前节点的两侧,则当前节点即为最近的公共祖先。

2024-08-26

由于篇幅限制,这里只列出了第30题和第70题的解决方案。

  1. 搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜索搜

题目描述:

你在玩一个猜数游戏,目标是猜出一个4位数(无重复数字的4位数)。

对方每次会告诉你有多少位数字正确且位置正确,有多少位数字正确但是位置不正确。

例如,对方的数字为"1234",你的猜测为"5678",则会有如下反馈:

  • 1 bull and 3 cows,因为"1"是位置正确的,而"3"、"6"、"7"、"8"都是数字正确但位置不正确。

编写一个函数,接收对方的数字和你的猜测,返回一个字符串表示答案。

示例:




secret = "1843"
guess = "3715"
 
返回 "1A3B" 表示有1个牛和3个牛的数字。

解决方案:




#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
 
char * getHint(char * secret, char * guess) {
    int bulls = 0;
    int cows = 0;
    bool used[10] = {false};
 
    for (int i = 0; i < strlen(secret); i++) {
        if (secret[i] == guess[i]) {
            bulls++;
        } else {
            if (!used[secret[i] - '0']) {
                used[secret[i] - '0'] = true;
                cows++;
            }
            if (!used[guess[i] - '0']) {
                used[guess[i] - '0'] = true;
                cows++;
            }
        }
    }
 
    char *result = malloc(4);
    sprintf(result, "%dA%dB", bulls, cows - bulls);
    return result;
}

这段代码首先计算出正确的牛的数量,然后通过一个标记数组来计算出正确的牛的数量。最后,使用sprintf函数将计算结果格式化为字符串。这个字符串是函数返回的答案。

2024-08-23

题目描述:

在2024年,你将会面临一个新的挑战,HTML5移动Web开发。你将会需要一个结合了现代Web技术和移动设备优势的解决方案。你将会需要一个可以响应用户输入,并且能够在移动设备上流畅运行的应用程序。

你将会需要一个可以运行在iOS和Android设备上的HTML5应用程序,它需要有以下特性:

  • 响应式布局
  • 可以运行在移动浏览器中
  • 能够处理触摸事件
  • 能够使用地理位置API
  • 能够使用加速度计
  • 能够使用文件系统API
  • 能够使用设备摄像头
  • 能够使用Web Workers
  • 能够使用Service Workers
  • 能够使用Web Storage API
  • 能够使用WebGL
  • 能够使用WebAssembly
  • 能够使用Push API
  • 能够使用Web Notification API
  • 能够使用WebVR API
  • 能够使用Web Audio API
  • 能够使用Web Animations API
  • 能够使用Fetch API
  • 能够使用Cache Storage API
  • 能够使用Background Sync API
  • 能够使用Payment Request API
  • 能够使用Web Share API
  • 能够使用WebRTC API

你将会需要一个可以测试这些特性的环境,并且能够在实际设备上进行测试。你将会需要一个可以帮助你理解这些新技术如何工作的教程。

你将会需要一个可以帮助你快速开始构建这样的应用程序的指南。

你将会需要一个可以提供实时帮助和解决问题的社区。

你将会需要一个可以展示如何构建高质量代码的示例。

你将会需要一个可以教你如何优化你的应用程序的性能和用户体验的指南。

你将会需要一个可以展示如何部署和发布你的应用程序的指南。

你将会需要一个可以教你如何进行访问性测试和可访问性优化的指南。

你将会需要一个可以教你如何进行性能分析和优化的指南。

你将会需要一个可以教你如何进行用户研究和A/B测试的指南。

你将会需要一个可以教你如何进行应用程序安全性审计和加强应用程序安全性的指南。

你将会需要一个可以教你如何进行移动应用程序的市场营销和推广的指南。

你将会需要一个可以教你如何持续集成和部署你的应用程序的指南。

你将会需要一个可以教你如何创建高质量的文档和教程的指南。

你将会需要一个可以教你如何进行用户支持和客户服务的指南。

你将会需要一个可以教你如何进行项目管理和团队协作的指南。

你将会需要一个可以教你如何进行持续学习和更新知识的指南。

你将会需要一个可以教你如何进行风险评估和业务案例分析的指南。

你将会需要一个可以教你如何进行品牌推广和市场营销的指南。

你将会需要一个可以教你如何进行合规性测试和遵守相关法规的指南。

你将会需要一个可以教你如何进行风险管理和

2024-08-21

题目:给你一个字符串 s ,请你返回 s 中最长的满足如下条件的子字符串的长度:每个元音字母在子字符串中的出现次数都是偶数。

元音字母包括 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'

示例 1:

输入:s = "eleetminicoworoep"

输出:13

解释:子字符串是 "minicowor" ,它包含 'a','e','i','o' 各 2 个,总共 8 个元音字母,满足每个元音字母出现次数都是偶数。

示例 2:

输入:s = "leetcodeisgreat"

输出:5

解释:子字符串是 "leetc" ,它包含 'e' 和 'i' 各 2 个,满足每个元音字母出现次数都是偶数。

示例 3:

输入:s = "bcbcbc"

输出:0

解释:没有子字符串满足条件,因此返回 0 。

提示:

  • 1 <= s.length <= 10^5
  • s 只包含小写或大写英文字母。

Java 解法:




class Solution {
    public int findTheLongestSubstringWithEvenNumberOfVowels(String s) {
        int ans = 0, count = 0;
        boolean[] vowel = new boolean[52];
        for (int i = 0; i < 26; i++) {
            vowel['a' + i] = true;
            vowel['A' + i] = true;
        }
        int[] last = new int[1];
        for (int i = 0; i < s.length(); i++) {
            if (vowel[s.charAt(i)]) {
                count++;
            }
            while (count > 1 && i - last[0] > 0) {
                if (vowel[s.charAt(last[0])]) {
                    count--;
                }
                last[0]++;
            }
            ans = Math.max(ans, i - last[0] + 1);
        }
        return ans;
    }
}

JavaScript 解法:




var findTheLongestSubstringWithEvenNumberOfVowels = function(s) {
    let ans = 0, count = 0;
    const vowel = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']);
    let last = -1;
    for (let i = 0; i < s.length; i++) {
        if (vowel.has(s[i])) {
            count++;
        }
        while (count > 1 && i - last > 0) {
            if (vowel.has(s[last + 1])) {
                count--;
            }
            last++;
        }
        ans = Math.max(ans, i - last);
    }
    return ans;
};

Python 解法:




class Solution:
    def findTheLongestSubstringWithEvenNumberOfVowels(self, s: str) -> int:
        ans = 0
        count = 0
        vowel = set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'])
        last = -1
        for i in range(len(s)):
            if s[i] in vowel:
                count += 1
            while count > 1 and i - last > 0:
                if s[last + 1] in vowel:
                    count -= 1
                last += 1
            ans = max(ans, i - last)
        return ans

C 解法:




#
2024-08-19



#include <iostream>
#include <string>
 
using namespace std;
 
class Solution {
public:
    string reverseOnlyLetters(string s) {
        int i = 0, j = s.size() - 1;
        while (i < j) {
            // 找到第一个字母和最后一个字母交换
            while (i < j && !isalpha(s[i])) i++;
            while (i < j && !isalpha(s[j])) j--;
            if (i < j) {
                swap(s[i++], s[j--]);
            }
        }
        return s;
    }
};
 
int main() {
    Solution solution;
    string input = "ab-cd-ef";
    cout << "Original string: " << input << endl;
    cout << "Reversed letters only: " << solution.reverseOnlyLetters(input) << endl;
    return 0;
}

这段代码定义了一个Solution类,其中包含了reverseOnlyLetters成员函数,该函数实现了反转字符串中的所有字母,而保留非字母字符原位置不变的功能。然后在main函数中创建了Solution类的实例并调用了reverseOnlyLetters方法,最后输出了处理后的字符串。