随着人工智能技术的发展,自然语言处理(Natural Language Processing,NLP)越来越受到关注。自然语言处理是一种使计算机能够理解、处理、生成自然语言的技术。在LeetCode上,也有很多与NLP相关的Java题目。本文将为大家介绍LeetCode上的一些与NLP相关的Java题目,并提供相应的代码演示。
- Reverse Words in a String
题目描述:
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue" 输出: "blue is sky the"
示例 2:
输入: " hello world! " 输出: "world! hello" 解释: 输入字符串可以在前面或后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: "a good example" 输出: "example good a" 解释: 输入字符串可以在前面或后面包含多余的空格,但是反转后的字符不能包括。
解题思路:
本题的解题思路比较简单,只需要将字符串按照空格分割成单词,然后逆序输出即可。代码如下:
class Solution {
public String reverseWords(String s) {
String[] words = s.trim().split(" +");
Collections.reverse(Arrays.asList(words));
return String.join(" ", words);
}
}
- Longest Substring Without Repeating Characters
题目描述:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解题思路:
本题的解题思路比较复杂,需要用到滑动窗口的思想。具体来说,我们维护一个滑动窗口,当窗口中出现重复字符时,就将窗口的左边界向右移动,直到窗口中不再有重复字符为止。代码如下:
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<>();
for (int i = 0, j = 0; j < n; j++) {
if (map.containsKey(s.charAt(j))) {
i = Math.max(map.get(s.charAt(j)), i);
}
ans = Math.max(ans, j - i + 1);
map.put(s.charAt(j), j + 1);
}
return ans;
}
}
- Valid Parentheses
题目描述:
给定一个只包括 "(",")","{","}","[","]" 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 注意空字符串可被认为是有效字符串。
示例 1:
输入: "()" 输出: true
示例 2:
输入: "()[]{}" 输出: true
示例 3:
输入: "(]" 输出: false
示例 4:
输入: "([)]" 输出: false
示例 5:
输入: "{[]}" 输出: true
解题思路:
本题的解题思路比较简单,只需要维护一个栈,遇到左括号就将其入栈,遇到右括号就将栈顶元素弹出,并判断两者是否匹配即可。代码如下:
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == "(" || c == "{" || c == "[") {
stack.push(c);
} else {
if (stack.isEmpty() || !isMatch(stack.peek(), c)) {
return false;
}
stack.pop();
}
}
return stack.isEmpty();
}
private boolean isMatch(char c1, char c2) {
return (c1 == "(" && c2 == ")") || (c1 == "{" && c2 == "}") || (c1 == "[" && c2 == "]");
}
}
- String to Integer (atoi)
题目描述:
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
示例 1:
输入: "42" 输出: 42
示例 2:
输入: " -42" 输出: -42 解释: 第一个非空白字符为 "-", 它是一个负号。 我们尽可能将负号与数值相连,最后得到 -42 。
示例 3:
输入: "4193 with words" 输出: 4193 解释: 转换截止于数字 "3" ,因为它的下一个字符不为数字。
示例 4:
输入: "words and 987" 输出: 0 解释: 第一个非空字符是 "w", 但它不是数字或正、负号。 因此无法执行有效的转换。
示例 5:
输入: "-91283472332" 输出: -2147483648 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 因此返回 INT_MIN (−231) 。
解题思路:
本题的解题思路比较复杂,需要考虑很多细节。具体来说,我们需要考虑以下几个方面:
- 去除字符串前面的空格;
- 判断字符串的第一个非空白字符是不是正号或负号;
- 将字符串转换成整数,如果超过了整数的范围,则返回边界值。
代码如下:
class Solution {
public int myAtoi(String s) {
int index = 0, sign = 1, total = 0;
if (s.length() == 0) {
return 0;
}
while (s.charAt(index) == " " && index < s.length()) {
index++;
}
if (index == s.length()) {
return 0;
}
if (s.charAt(index) == "+" || s.charAt(index) == "-") {
sign = s.charAt(index) == "+" ? 1 : -1;
index++;
}
while (index < s.length()) {
int digit = s.charAt(index) - "0";
if (digit < 0 || digit > 9) {
break;
}
if (Integer.MAX_VALUE / 10 < total || Integer.MAX_VALUE / 10 == total && Integer.MAX_VALUE % 10 < digit) {
return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
total = total * 10 + digit;
index++;
}
return total * sign;
}
}
结语
以上就是LeetCode上的一些与NLP相关的Java题目。这些题目虽然看起来比较复杂,但只要我们掌握了相应的算法思想,就能够轻松解决这些问题。希望本文能够对大家有所帮助。