This commit is contained in:
wyl
2024-06-24 18:28:58 +08:00
parent 6b47e57126
commit 9d795c5abc
7 changed files with 509 additions and 0 deletions
@@ -0,0 +1,133 @@
package com.wyl.leetcode;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* 6.将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
* 比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
* <p>
* P A H N
* A P L S I I G
* Y I R
* 之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
* <p>
* 请你实现这个将字符串进行指定行数变换的函数:
* <p>
* string convert(string s, int numRows);
* <p>
* <p>
* 示例 1
* <p>
* 输入:s = "PAYPALISHIRING", numRows = 3
* 输出:"PAHNAPLSIIGYIR"
* 示例 2
* 输入:s = "PAYPALISHIRING", numRows = 4
* 输出:"PINALSIGYAHRPI"
* 解释:
* P I N
* A L S I G
* Y A H R
* P I
* 示例 3
* <p>
* 输入:s = "A", numRows = 1
* 输出:"A"
*/
public class ConvertZ {
static public String convert(String s, int numRows) {
int length = s.length();
String[] split = s.split("");
int l = 0;
int a = ((int) Math.ceil(length / (2.0 * numRows - 2))) * (numRows - 1);
if (numRows == 1) {
return s;
}
String[][] res = new String[numRows][a];
for (int i = 0; i < a && l < length; i++) {
int tmp = i % (numRows - 1);
if (tmp == 0) {
for (int j = 0; j < numRows && l < length; j++) {
res[j][i] = split[l];
l++;
}
} else {
res[numRows - 1 - tmp][i] = split[l];
l++;
}
}
String resut = "";
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < a; j++) {
String s1 = res[i][j];
if (Objects.nonNull(s1)) {
resut = resut + s1;
}
}
}
return resut;
}
/**
* 更加优化
* P I N
* A L S I G
* Y A H R
* P I
* 等于
* P I N
* ALSIG
* YAHR
* P I
*
* @param s
* @param numRows
* @return java.lang.String
* @Date 2024/6/24
* @Author wangyl
*/
public String convert1(String s, int numRows) {
if (numRows <= 1) {
return s;
}
List<StringBuilder> list = new ArrayList<>();
for (int i = 0; i < numRows; i++) {
list.add(new StringBuilder());
}
int index = 0;
int end = numRows - 1;
// true: 从上往下,false: 从下往上
boolean flag = true;
for (char c : s.toCharArray()) {
list.get(index).append(c);
if (flag) {
// 到底了更新flag开始往上
if (index == end) {
flag = false;
index--;
} else {
index++;
}
} else {
// 回到顶端了更新flag开始往下
if (index == 0) {
flag = true;
index++;
} else {
index--;
}
}
}
StringBuilder ret = new StringBuilder();
for (StringBuilder sb : list) {
ret.append(sb);
}
return ret.toString();
}
public static void main(String[] args) {
System.out.println(convert("A", 1));
}
}
@@ -0,0 +1,59 @@
package com.wyl.leetcode;
import java.util.ArrayList;
import java.util.List;
/**
* 4.给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
* <p>
* 算法的时间复杂度应该为 O(log (m+n)) 。
* <p>
* <p>
* 示例 1
* <p>
* 输入:nums1 = [1,3], nums2 = [2]
* 输出:2.00000
* 解释:合并数组 = [1,2,3] ,中位数 2
* 示例 2
* <p>
* 输入:nums1 = [1,2], nums2 = [3,4]
* 输出:2.50000
* 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
*/
public class FindMedianSortedArrays {
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
List<Integer> res = new ArrayList<>();
int nums1Length = nums1.length;
int nums2Length = nums2.length;
int a1 = 0;
int a2 = 0;
while (a1 < nums1Length || a2 < nums2Length) {
int i1 = Integer.MAX_VALUE;
int i2 = Integer.MAX_VALUE;
if (a1 < nums1Length) {
i1 = nums1[a1];
}
if (a2 < nums2Length) {
i2 = nums2[a2];
}
if (i1 < i2) {
res.add(i1);
a1++;
} else {
res.add(i2);
a2++;
}
}
int all = nums1Length + nums2Length;
if (all % 2 == 0) {
return (res.get((all / 2) - 1) + res.get((all / 2))) / 2.0;
} else {
return res.get(((all + 1) / 2) - 1);
}
}
public static void main(String[] args) {
System.out.println(findMedianSortedArrays(new int[]{1, 2}, new int[]{3, 4}));
}
}
@@ -0,0 +1,54 @@
package com.wyl.leetcode;
import java.util.HashSet;
import java.util.Set;
/**
* 3.给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度。
* <p>
* 示例 1:
* <p>
* 输入: s = "abcabcbb"
* 输出: 3
* 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
* 示例 2:
* <p>
* 输入: s = "bbbbb"
* 输出: 1
* 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
* 示例 3:
* <p>
* 输入: s = "pwwkew"
* 输出: 3
* 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
* 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
*/
public class LengthOfLongestSubstring {
public static int lengthOfLongestSubstring(String s) {
Set<Byte> tmp = new HashSet<>();
byte[] split = s.getBytes();
if (split.length == 1) {
return 1;
}
int l = 0;
int r = 0;
int max = 0;
while (r < split.length) {
if (!tmp.contains(split[r])) {
tmp.add(split[r]);
r++;
} else {
max = Math.max(tmp.size(), max);
tmp.remove(split[l]);
l++;
}
}
return Math.max(tmp.size(), max);
}
public static void main(String[] args) {
String s = "bbbbbbbc";
System.out.println(lengthOfLongestSubstring(s));
}
}
@@ -0,0 +1,74 @@
package com.wyl.leetcode;
/**
* 5.给你一个字符串 s,找到 s 中最长的回文子串
* 。
* <p>
* 示例 1
* <p>
* 输入:s = "babad"
* 输出:"bab"
* 解释:"aba" 同样是符合题意的答案。
* 示例 2
* <p>
* 输入:s = "cbbd"
* 输出:"bb"
*/
public class LongestPalindrome {
/**
* 暴力解法超时
* s = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
*/
public static String longestPalindrome(String s) {
String max = "";
String[] split = s.split("");
for (int i = 0; i < split.length; i++) {
for (int j = i; j < split.length; j++) {
String tmp = s.substring(i, j + 1);
if (isPalindrome(split, i, j)) {
if (max.length() < tmp.length()) {
max = tmp;
}
}
}
}
return max;
}
/**
* 判断是否是回文
*
* @param split
* @param start
* @param end
* @return boolean
* @Date 2024/6/24
* @Author wangyl
*/
static private boolean isPalindrome(String[] split, int start, int end) {
while (start < end) {
if (split[start].equals(split[end])) {
start++;
end--;
} else {
return false;
}
}
return true;
}
/**
* 中心扩展法
* @param s
* @return java.lang.String
* @Date 2024/6/24
* @Author wangyl
*/
static private String CenterDiffusion(String s)
{
return "";
}
public static void main(String[] args) {
System.out.println(longestPalindrome("babad"));
}
}
@@ -0,0 +1,58 @@
package com.wyl.leetcode;
/**
* 给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
* <p>
* 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
* <p>
* 假设环境不允许存储 64 位整数(有符号或无符号)。
* <p>
* <p>
* 示例 1
* <p>
* 输入:x = 123
* 输出:321
* 示例 2
* <p>
* 输入:x = -123
* 输出:-321
* 示例 3
* <p>
* 输入:x = 120
* 输出:21
* 示例 4
* <p>
* 输入:x = 0
* 输出:0
*/
public class Reverse {
/**
* 核心问题处理越界,再处理最后一位之前就要判断是不是不能继续增加了 最后一位要小于7 要不就越界了
*
* @param x
* @return int
* @Date 2024/6/24
* @Author wangyl
*/
public static int reverse(int x) {
int res = 0;
while (Math.abs(x) != 0) {
int tmp = x % 10;
if (res > 214748364 || (res == 214748364 && tmp > 7)) {
return 0;
}
if (res < -214748364 || (res == -214748364 && tmp < -8)) {
return 0;
}
res = (res * 10 + tmp);
x = x / 10;
}
return res;
}
public static void main(String[] args) {
System.out.println(reverse(-2147483648));
}
}
@@ -0,0 +1,43 @@
package com.wyl.leetcode;
import java.util.Arrays;
/**
* 1. 两数之和
* 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
* 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
* 你可以按任意顺序返回答案。
* <p>
* 示例 1
* <p>
* 输入:nums = [2,7,11,15], target = 9
* 输出:[0,1]
* 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
* 示例 2
* <p>
* 输入:nums = [3,2,4], target = 6
* 输出:[1,2]
* 示例 3
* <p>
* 输入:nums = [3,3], target = 6
* 输出:[0,1]
*/
public class SumTwoNumber {
public static int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (target == nums[i] + nums[j]) {
res[0] = i;
res[1] = j;
return res;
}
}
}
return res;
}
public static void main(String[] args) {
Arrays.stream(twoSum(new int[]{2, 5, 5, 11}, 10)).forEach(System.out::println);
}
}
@@ -0,0 +1,88 @@
package com.wyl.leetcode;
import java.util.Objects;
/**
* 2 给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
* <p>
* 请你将两个数相加,并以相同形式返回一个表示和的链表。
* <p>
* 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
* <p>
* 示例 1
* <p>
* <p>
* 输入:l1 = [2,4,3], l2 = [5,6,4]
* 输出:[7,0,8]
* 解释:342 + 465 = 807.
* 示例 2
* <p>
* 输入:l1 = [0], l2 = [0]
* 输出:[0]
* 示例 3
* <p>
* 输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
* 输出:[8,9,9,9,0,0,0,1]
*/
public class SumTwoNumber2 {
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode res = null;
ListNode resCur = null;
int tmp = 0;
ListNode l1Cur = l1;
ListNode l2Cur = l2;
while (Objects.nonNull(l1Cur) || Objects.nonNull(l2Cur)) {
int l1Val = 0;
int l2Val = 0;
if (Objects.nonNull(l1Cur)) {
l1Val = l1Cur.val;
l1Cur = l1Cur.next;
}
if (Objects.nonNull(l2Cur)) {
l2Val = l2Cur.val;
l2Cur = l2Cur.next;
}
int val = l1Val + l2Val + tmp;
tmp = val / 10;
if (Objects.isNull(res)) {
res = new ListNode(val % 10, resCur);
resCur = res;
} else {
ListNode listNode = new ListNode(val % 10);
resCur.next = listNode;
resCur = listNode;
}
}
if (tmp > 0) {
resCur.next = new ListNode(tmp);
}
return res;
}
public static void main(String[] args) {
ListNode l1 = new ListNode(5, new ListNode(6));
ListNode l2 = new ListNode(5, new ListNode(4, new ListNode(9)));
ListNode listNode = addTwoNumbers(l1, l2);
while (listNode != null) {
System.out.println(listNode.val);
listNode = listNode.next;
}
}
static public class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
}