当前位置:   article > 正文

leetcode题库

leetcode题库

一、两数之和

原题链接

  • 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
  • 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
  • 你可以按任意顺序返回答案。

Python解法

1、暴力解法

  1. class Solution(object):
  2. def twoSum(self, nums, target):
  3. """
  4. :type nums: List[int]
  5. :type target: int
  6. :rtype: List[int]
  7. """
  8. #获取nums数组的长度
  9. n = len(nums)
  10. #两次循环
  11. for i in range(n - 1):
  12. for j in range(i + 1, n):
  13. if target == nums[i] + nums[j]:
  14. return [i, j]
  15. #若是没有找到则返回[]空列表
  16. return []

2、dict集合(哈希表)解法

  1. class Solution(object):
  2. def twoSum(self, nums, target):
  3. """
  4. :type nums: List[int]
  5. :type target: int
  6. :rtype: List[int]
  7. """
  8. #创建一个空dict集合
  9. num_to_index = dict()
  10. #使用enumerate()方法获取nums数组的 (索引,值)的迭代器对象,并进行遍历
  11. for index,num in enumerate(nums):
  12. complement = target - num #计算与当前数字匹配的补数
  13. if complement in num_to_index:
  14. return [num_to_index[complement], index] # 找到补数在哈希表中的索引,以及当前数字的索引
  15. num_to_index[num] = index # 将当前数字添加到哈希表中
  16. return [] # 如果没有找到匹配的组合,返回空列表

Java解法

1、暴力解法

  1. class Solution {
  2. public int[] twoSum(int[] nums, int target) {
  3. int n = nums.length;
  4. for(int i = 0; i < n - 1; i++){
  5. for(int j = i + 1; j < n; j++){
  6. if(nums[i] + nums[j] == target){
  7. return new int[]{i, j};
  8. }
  9. }
  10. }
  11. return new int[]{};
  12. }
  13. }

2、HashMap集合(哈希表)解法

  1. class Solution {
  2. public int[] twoSum(int[] nums, int target) {
  3. HashMap<Integer, Integer> hashMap = new HashMap<>();
  4. for (int i = 0; i < nums.length; i++) {
  5. int complement = target - nums[i];
  6. if (hashMap.containsKey(complement)) {
  7. return new int[]{hashMap.get(complement), i};
  8. }
  9. hashMap.put(nums[i], i);
  10. }
  11. return new int[]{};
  12. }
  13. }

二、两数相加

原题链接

  • 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
  • 请你将两个数相加,并以相同形式返回一个表示和的链表。
  • 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

Python解法

  1. class ListNode(object):
  2. def __init__(self, val = 0, next = None):
  3. self.val = val
  4. self.next = next
  5. class Solution(object):
  6. def addTwoNumbers(self, l1, l2):
  7. virtual_head = ListNode()
  8. current = virtual_head
  9. carray = 0
  10. while l1 is not None or l2 is not None or carray != 0:
  11. val1 = l1.val if l1 is not None else 0
  12. val2 = l2.val if l2 is not None else 0
  13. total = val1 + val2 + carray
  14. carray = total // 10
  15. current.next = ListNode(total % 10)
  16. current = current.next
  17. if l1 is not None:
  18. l1 = l1.next
  19. if l2 is not None:
  20. l2 = l2.next
  21. return virtual_head.next
  22. def print_list(self,head):
  23. while head is not None:
  24. print(head.val," -> ",end="")
  25. head = head.next
  26. print("None")
  27. def main(self):
  28. l1 = ListNode(9,ListNode(9))
  29. l2 = ListNode(1,ListNode(1))
  30. self.print_list(self.addTwoNumbers(l1, l2))
  31. if __name__ == '__main__':
  32. s = Solution()
  33. s.main()

Java解法

  1. /**
  2. * 单链表中的节点:
  3. * 节点是单链表中的基本单元
  4. * 每一个节点Node都有两个属性
  5. * 一个属性:是存储的数据
  6. * 另一个属性:是下一个节点的内存地址
  7. */
  8. class ListNode {
  9. //实例变量 val 存储的数据
  10. int val;
  11. //实例变量 next 下一个节点的引用(内存地址)
  12. ListNode next;
  13. ListNode() {}
  14. ListNode(int val) { this.val = val; }
  15. ListNode(int val, ListNode next) { this.val = val; this.next = next; }
  16. }
  17. public class AddTwoNumbers {
  18. public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
  19. ListNode dummyHead = new ListNode(0); // 创建一个虚拟头节点
  20. ListNode current = dummyHead; // 指向当前节点的指针
  21. int carry = 0; // 进位的初始值为0
  22. while (l1 != null || l2 != null || carry != 0) {
  23. int val1 = l1 != null ? l1.val : 0; // 获取链表l1当前节点的值,如果为null,则默认为0
  24. int val2 = l2 != null ? l2.val : 0; // 获取链表l2当前节点的值,如果为null,则默认为0
  25. int total = val1 + val2 + carry; // 计算当前位的和,加上进位
  26. carry = total / 10; // 更新进位
  27. current.next = new ListNode(total % 10); // 创建新节点,存储当前位的值
  28. current = current.next; // 移动当前指针到新节点
  29. if (l1 != null) l1 = l1.next; // 如果链表l1还有下一个节点,移动l1指针到下一个节点
  30. if (l2 != null) l2 = l2.next; // 如果链表l2还有下一个节点,移动l2指针到下一个节点
  31. }
  32. return dummyHead.next; // 返回虚拟头节点的下一个节点作为结果链表的头节点
  33. }
  34. public static void printList(ListNode head) {
  35. while (head != null) {
  36. System.out.print(head.val + " -> "); // 输出节点的值
  37. head = head.next; // 移动指针到下一个节点
  38. }
  39. System.out.println("null"); // 输出链表结束标志
  40. }
  41. public static void main(String[] args) {
  42. AddTwoNumbers solution = new AddTwoNumbers();
  43. // 创建示例链表:342 表示为 2->4->3
  44. ListNode l1 = new ListNode(2, new ListNode(4, new ListNode(3)));
  45. ListNode l2 = new ListNode(5, new ListNode(6, new ListNode(4)));
  46. ListNode result = solution.addTwoNumbers(l1, l2);
  47. printList(result); // 输出: 7 -> 0 -> 8 -> null
  48. }
  49. }

三、无重复字符的最长子串

原题链接

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

Python解法

  1. class Solution:
  2. def lengthOfLongestSubstring(self, s: str) -> int:
  3. char_list = list()
  4. max_lenght = 0
  5. left = 0
  6. for right in range(len(s)):
  7. current_char = s[right]
  8. while current_char in char_list:
  9. char_list.remove(s[left])
  10. left += 1
  11. char_list.append(current_char)
  12. max_lenght = max(max_lenght, len(char_list))
  13. return max_lenght

Java解法

  1. import java.util.*;
  2. /**
  3. * 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
  4. */
  5. public class LengthOfLongestSubstring {
  6. public int lengthOfLongestSubstring(String s){
  7. ArrayList<Character> list = new ArrayList<>(); //用于存储当前窗口中的字符
  8. int maxLength = 0; //记录最长子串的长度
  9. int left = 0; //左指针,窗口的起始位置
  10. for (int right = 0; right < s.length(); right++){
  11. while (list.contains(s.charAt(right))){
  12. list.remove((Character) s.charAt(left));
  13. left++;
  14. }
  15. list.add(s.charAt(right));
  16. maxLength = Math.max(maxLength, right - left + 1);
  17. }
  18. return maxLength;
  19. }
  20. public static void main(String[] args) {
  21. LengthOfLongestSubstring l = new LengthOfLongestSubstring();
  22. System.out.println(l.lengthOfLongestSubstring("pwwkew"));
  23. }
  24. }

四、最长回文串

原题链接

给你一个字符串 s,找到 s 中最长的回文子串

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串

Python解法

1、暴力解法

  1. class Solution:
  2. def longestPalindrome(self, s: str) -> str:
  3. s_length = len(s)
  4. if s_length < 2:
  5. return s
  6. max_length = 1
  7. start = 0
  8. char_list = list(s)
  9. for i in range(s_length - 1):
  10. for j in range(i + 1, s_length):
  11. if j - i + 1 > max_length and self.valicPalindromic(char_list, i, j):
  12. max_length = j - i + 1
  13. start = i
  14. return "".join(char_list[start: start + max_length])
  15. def valicPalindromic(self, char_list, left, right):
  16. while left < right:
  17. if char_list[left] != char_list[right]:
  18. return False
  19. left += 1
  20. right -= 1
  21. return True

2、中心扩展解法

  1. def expandAroundCenter(s, left, right):
  2. while left >= 0 and right < len(s) and s[left] == s[right]:
  3. left -= 1
  4. right += 1
  5. return s[left + 1:right]
  6. def longestPalindrome(s):
  7. n = len(s)
  8. if n < 2:
  9. return s
  10. start = 0
  11. end = 0
  12. for i in range(n):
  13. len1 = len(expandAroundCenter(s, i, i))
  14. len2 = len(expandAroundCenter(s, i, i + 1))
  15. max_len = max(len1, len2)
  16. if max_len > end - start:
  17. start = i - (max_len - 1) // 2
  18. end = i + max_len // 2
  19. return s[start:end + 1]
  20. # 示例用法
  21. s = "babad"
  22. result = longestPalindrome(s)
  23. print(result) # 输出 "bab" 或 "aba"

Java解法

1、暴力解法

  1. class Solution {
  2. public boolean validPalindromic(char[] charArray, int left, int right){
  3. while(left < right){
  4. if(charArray[left] != charArray[right]){
  5. return false;
  6. }
  7. left++;
  8. right--;
  9. }
  10. return true;
  11. }
  12. public String longestPalindrome(String s){
  13. int len = s.length();
  14. if(len < 2){
  15. return s;
  16. }
  17. int maxLen = 1;
  18. int start = 0;
  19. char[] charArray = s.toCharArray();
  20. for(int i = 0; i < len - 1; i++){
  21. for(int j = i + 1; j < len; j++){
  22. if(j - i + 1 > maxLen && validPalindromic(charArray, i, j)){
  23. maxLen = j - i + 1;
  24. start = i;
  25. }
  26. }
  27. }
  28. return s.substring(start, start + maxLen);
  29. }
  30. }

2、中心扩展解法

  1. public class LongestPalindromic{
  2. public String expandAroundCenter(String s, int left, int right){
  3. while(left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)){
  4. left--;
  5. right++;
  6. }
  7. return s.substring(left + 1, right);
  8. }
  9. public String longestPalindromic(String s){
  10. int len = s.length();
  11. if(len < 2){
  12. return s;
  13. }
  14. int start = 0;
  15. int end = 0;
  16. for(int i = 0; i < len; i++){
  17. int oddLen = expandAroundCenter(s, i, i).length();
  18. int evenLen = expandAroundCenter(s, i, i + 1).length();
  19. int maxLen = Math.max(oddLen, evenLen);
  20. if(maxLen > end - start){
  21. start = i - (maxLen - 1) / 2;
  22. end = i + maxLen / 2;
  23. }
  24. }
  25. return s.substring(start, end + 1);
  26. }
  27. public static void main(String[] args){
  28. LongestPalindromic l = new LongestPalindromic();
  29. String s = "cbbd";
  30. String result = l.longestPalindromic(s);
  31. System.out.println(result);
  32. }
  33. }

五、N字形变换

原题链接

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

Python解法

  1. class Solution(object):
  2. def convert(self, s:str, numRows:int) -> str:
  3. n, r = len(s), numRows
  4. if r == 1 or n <= r:
  5. return s
  6. t = 2 * r - 2
  7. c = (n + t) // t * (r - 1)
  8. my_list = [[None] * c for i in range(r)]
  9. x = 0
  10. y = 0
  11. for i in range(n):
  12. my_list[y][x] = s[i]
  13. if i % t < r - 1:
  14. y += 1
  15. else:
  16. y -= 1
  17. x += 1
  18. return_list = list()
  19. for row in my_list:
  20. for col in row:
  21. if col is not None:
  22. return_list.append(col)
  23. return "".join(return_list)
  24. if __name__ == "__main__":
  25. s = Solution()
  26. print(s.convert("PAYPALISHIRING", 3))

Java解法

  1. import java.lang.StringBuilder;
  2. public class Solution{
  3. public String convert(String s, int numRows){
  4. //n为传入的字符串中的字符个数
  5. //r为行数
  6. int n = s.length(), r = numRows;
  7. //如果行数为1 或者 字符总个数小于等于行数的话,说明只需要1列就行,所以直接返回该字符串
  8. if(r == 1 || n <= r){
  9. return s;
  10. }
  11. //一个周期内的字符个数为 行数 + 行数 - 2 = 2行数 - 2
  12. int t = 2 * r - 2;
  13. //列数,每个周期的列数为 1 + 行数 - 2 = 行数 - 1
  14. //(n + t) 表示给原始字符中的字符个数在加一个周期,害怕若是不能整除计算错列数,列数可以多但不能少
  15. int c = (n + t) / t * (r - 1);
  16. //创建一个 r行,c列的二维字符数组
  17. //二维数组中r表示行数,c表示每一行中的列数
  18. char[][] chars = new char[r][c];
  19. //使用for循环在二维数组中放置元素
  20. //i表示字符串中每个字符的索引下标
  21. //x表示列数
  22. //y表示行数
  23. for(int i = 0, x = 0, y = 0; i < n; i++){
  24. //先在第一行第一列的位置处放置第一个元素
  25. chars[y][x] = s.charAt(i);
  26. //判断什么时候应该往下放元素,什么时候应该往右上放元素
  27. //应该画图找规律
  28. if(i % t < r - 1){
  29. y++;
  30. }else{
  31. x++;
  32. y--;
  33. }
  34. }
  35. //创建一个字符串缓冲对象
  36. StringBuilder stringBuilder = new StringBuilder();
  37. //遍历二维数组
  38. for(char[] row: chars){
  39. //遍历一维数组
  40. for(char col: row){
  41. //根据字符的ASCII码进行判断该位置处是否有元素
  42. //char的默认值为 /u0000 换算成十进制为 0,因此不等于0时,该位置处必有元素
  43. if(col != 0){
  44. //将该元素添加至字符串缓存对象中
  45. stringBuilder.append(col);
  46. }
  47. }
  48. }
  49. //返回字符串缓存对象的字符串表示形式
  50. return stringBuilder.toString();
  51. }
  52. public static void main(String[] args){
  53. Solution solution = new Solution();
  54. String s = "PAYPALISHIRING";
  55. int numRows = 3;
  56. String result = solution.convert(s, numRows);
  57. System.out.println(result);
  58. }
  59. }

六、整数反转

原题链接

  1. 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
  2. 如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。
  3. 假设环境不允许存储 64 位整数(有符号或无符号)。

Python解法

  1. class IntegerInversion(object):
  2. def reverse(self, x:int) -> int:
  3. #将int不可迭代类型转换为str可迭代类型
  4. strInt = str(x)
  5. #将str可迭代类型转换转换为list可迭代类型
  6. strList = list(strInt)
  7. #判断其第一个元素是否为“-” 号
  8. if strList[0] == "-":
  9. strListNoFirstElement = strList[1:]
  10. strListNoFirstElement.reverse()
  11. returnInt = int("-" + "".join(strListNoFirstElement))
  12. return returnInt if returnInt >= -2 **31 and returnInt <= 2 ** 31 -1 else 0
  13. strList.reverse()
  14. #将str类型转换为int类型返回
  15. returnInt = int("".join(strList))
  16. return returnInt if returnInt >= -2 **31 and returnInt <= 2 ** 31 -1 else 0

Java解法

  1. public class IntegerReverse{
  2. public int reverse(int x){
  3. long ans = 0;//自动类型转换,0默认为int类型,自动转换为long类型
  4. while(x != 0){
  5. //取余依次递推
  6. ans = ans * 10 + x % 10;
  7. x /= 10;
  8. }
  9. //将long类型的ans强制类型转换为int类型,若是ans没有超出int类型的取值范围 -2147483648 ~ 2147483647 之间
  10. //则强制类型转换后应该和原数相等,否则即为超出了int类型的取值范围,返回0
  11. return (int)ans == ans ? (int)ans : 0;
  12. }
  13. public static void main(String[] args){
  14. IntegerReverse s = new IntegerReverse(); //2147483647
  15. System.out.println(s.reverse(2147483647));
  16. }
  17. }

七、字符串转换整数(atoi)

原题链接

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

  1. 读入字符串并丢弃无用的前导空格
  2. 检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
  3. 读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
  4. 将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
  5. 如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
  6. 返回整数作为最终结果。

注意:

  • 本题中的空白字符只包括空格字符 ' ' 。
  • 除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

Python解法

  1. class Automation(object):
  2. def __init__(self):
  3. self.ans = 0
  4. self.sign = 1
  5. self.state = "start"
  6. self.MAX_VALUE = 2147483647
  7. self.MIN_VALUE = -2147483648
  8. self.table = {
  9. "start": ["start", "signed", "in_number", "end"],
  10. "signed": ["end", "end", "in_number", "end"],
  11. "in_number": ["end", "end", "in_number", "end"],
  12. "end": ["end", "end", "end", "end"]
  13. }
  14. def get_col(self, c):
  15. if c == " ":
  16. return 0
  17. if c == "+" or c == "-":
  18. return 1
  19. if c.isdigit():
  20. return 2
  21. return 3
  22. def get(self, c):
  23. self.state = self.table.get(self.state)[self.get_col(c)]
  24. if "in_number" == self.state:
  25. self.ans = self.ans * 10 + int(c)
  26. self.ans = min(self.ans, self.MAX_VALUE) if self.sign == 1 else min(self.ans, -self.MIN_VALUE)
  27. elif "signed" == self.state:
  28. self.sign = 1 if c == "+" else -1
  29. def main(self, s):
  30. for i in s:
  31. self.get(i)
  32. return self.sign * self.ans
  33. if __name__ == "__main__":
  34. a = Automation()
  35. s = "-1 23"
  36. print(a.main(s))

Java解法

  1. import java.util.Map;
  2. import java.util.HashMap;
  3. class Automation{
  4. //ans表示要返回的整数,不带符号
  5. public long ans = 0;
  6. //标志位,1表示为正数,-1表示为负数
  7. public int sign = 1;
  8. //state状态,默认状态为 start开始状态
  9. private String state = "start";
  10. //方法内部类语法
  11. private Map<String, String[]> table = new HashMap<>(){{
  12. put("start", new String[]{"start", "signed", "in_number", "end"});
  13. put("signed", new String[]{"end", "end", "in_number", "end"});
  14. put("in_number", new String[]{"end", "end", "in_number", "end"});
  15. put("end", new String[]{"end", "end", "end", "end"});
  16. }};
  17. //获取列号
  18. private int getCol(char c){
  19. //如果c为空格,则表示第一列
  20. if(c == ' ') return 0;
  21. //如果c为 - 或 + 符号 则表示第二列
  22. if(c == '+' || c == '-') return 1;
  23. //如果c为 数字,则表示第三列
  24. if(Character.isDigit(c)) return 2;
  25. //否则c为其他,表示第四列
  26. return 3;
  27. }
  28. public void get(char c){
  29. //获取当前的状态
  30. state = this.table.get(state)[this.getCol(c)];
  31. //如果当前状态为in_number
  32. if("in_number".equals(state)){
  33. //由于c是char类型,'0'所对应的ASCII码为48,用于获取char类型所对应的十进制数
  34. ans = ans * 10 + (c - '0');
  35. //取最小值
  36. ans = (sign == 1)? Math.min(ans, (long)Integer.MAX_VALUE): Math.min(ans, -(long)Integer.MIN_VALUE);
  37. }else if("signed".equals(state)){
  38. //在signed符号状态时给sign赋值
  39. //1 表示为正
  40. //-1 表示为负
  41. sign = (c == '+') ? 1 : -1;
  42. }
  43. }
  44. }
  45. public class Solution{
  46. public int maAtoi(String s){
  47. //创建automation对象
  48. Automation automation = new Automation();
  49. //遍历字符串中的每个字符
  50. for(int i = 0; i < s.length(); i++){
  51. automation.get(s.charAt(i));
  52. }
  53. //使用符号 * 值,转换为int类型返回
  54. return (int) (automation.sign * automation.ans);
  55. }
  56. public static void main(String[] args){
  57. Solution s = new Solution();
  58. String str = "-123";
  59. int result = s.maAtoi(str);
  60. System.out.println(result);
  61. }
  62. }

八、回文数

原文链接

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

  • 例如,121 是回文,而 123 不是。

Python解法

  1. class Solution:
  2. def isPalindrome1(self, x: int) -> bool:
  3. str_int = str(x)
  4. return str_int == str_int[::-1]
  5. def isPalindrome2(self, x: int) -> bool:
  6. if x < 0:
  7. return False
  8. reversed = 0
  9. original = x
  10. while x != 0:
  11. digit = x % 10
  12. reversed = reversed * 10 + digit
  13. x //= 10
  14. return reversed == original

Java解法

  1. public class Solution {
  2. public boolean isPalindrome1(int x){
  3. String strInt = String.valueOf(x);
  4. int length = strInt.length();
  5. for(int i = 0; i < length / 2; i++){
  6. if(strInt.charAt(i) != strInt.charAt(length - 1 - i)) return false;
  7. }
  8. return true;
  9. }
  10. public boolean isPalindrome2(int x){
  11. // 负数不能是回文数
  12. if (x < 0){
  13. return false;
  14. }
  15. // 计算 x 的反转数
  16. int reversed = 0;
  17. int original = x;
  18. while (x != 0){
  19. int digit = x % 10;
  20. reversed = reversed * 10 + digit;
  21. x /= 10;
  22. }
  23. // 如果反转后的数与原始数相等,则是回文数,否则不是
  24. return original == reversed;
  25. }
  26. public static void main(String[] args) {
  27. Solution s = new Solution();
  28. System.out.println(s.isPalindrome1(-232));
  29. }
  30. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/800734
推荐阅读
相关标签
  

闽ICP备14008679号