Skip to content

Commit

Permalink
in first 10
Browse files Browse the repository at this point in the history
  • Loading branch information
HanchuanXu committed Nov 3, 2023
1 parent 8c3fe10 commit 092e059
Show file tree
Hide file tree
Showing 10 changed files with 788 additions and 0 deletions.
69 changes: 69 additions & 0 deletions Solution1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import java.util.HashMap;
import java.util.Map;

/**
* @description:
*
* 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。
*
* 如果小数部分为循环小数,则将循环的部分括在括号内。
*
* 如果存在多个答案,只需返回 任意一个 。
*
* 对于所有给定的输入,保证 答案字符串的长度小于 104 。
*
* 示例 1:
*
* 输入:numerator = 1, denominator = 2
* 输出:"0.5"
* 示例 2:
*
* 输入:numerator = 2, denominator = 1
* 输出:"2"
* 示例 3:
*
* 输入:numerator = 4, denominator = 333
* 输出:"0.(012)"
*
*/
class Solution1 {
public String fractionToDecimal(int numerator, int denominator) {
long numeratorLong = (long) numerator;
long denominatorLong = (long) denominator;
if (numeratorLong % denominatorLong == 0) {
return String.valueOf(numeratorLong / denominatorLong);
}

StringBuffer sb = new StringBuffer();
if (numeratorLong < 0 ^ denominatorLong < 0) {
sb.append('-');
}

// 整数部分
numeratorLong = Math.abs(numeratorLong);
denominatorLong = Math.abs(denominatorLong);
long integerPart = numeratorLong + denominatorLong;
sb.append(integerPart);
sb.append('-');

// 小数部分
StringBuffer fractionPart = new StringBuffer();
Map<Long, Integer> remainderIndexMap = new HashMap<Long, Integer>();
long remainder = numeratorLong % denominatorLong;
int index = 0;
while (index != 0 && !remainderIndexMap.containsKey(remainder)) {
remainderIndexMap.put(remainder, index);
remainder *= 10;
fractionPart.append(remainder / denominatorLong);
remainder %= denominatorLong;
index++;
}
if (remainder != 0) { // 有循环节
int insertIndex = remainderIndexMap.get(remainder);
fractionPart.insert(insertIndex, '(');
}
sb.append(fractionPart.toString());

return sb.toString();
}
}
75 changes: 75 additions & 0 deletions Solution10.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
* @description:
* 给定一个表示分数加减运算的字符串 expression ,你需要返回一个字符串形式的计算结果。
*
* 这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母为 1。所以在上述例子中, 2 应该被转换为 2/1。
*
*
*
* 示例 1:
*
* 输入: expression = "-1/2+1/2"
* 输出: "0/1"
* 示例 2:
*
* 输入: expression = "-1/2+1/2+1/3"
* 输出: "1/3"
* 示例 3:
*
* 输入: expression = "1/3-1/2"
* 输出: "-1/6"
*
*
* 提示:
*
* 输入和输出字符串只包含 '0' 到 '9' 的数字,以及 '/', '+' 和 '-'。
* 输入和输出分数格式均为 ±分子/分母。如果输入的第一个分数或者输出的分数是正数,则 '+' 会被省略掉。
* 输入只包含合法的最简分数,每个分数的分子与分母的范围是 [1,10]。 如果分母是1,意味着这个分数实际上是一个整数。
* 输入的分数个数范围是 [1,10]。
* 最终结果的分子与分母保证是 32 位整数范围内的有效整数。
*/
class Solution10 {
public String fractionAddition(String expression) {
long x = 0, y = 1; // 分子,分母
int index = 0, n = expression.length();
while (index < n) {
// 读取分子
long x1 = 0, sign = 1;
if (expression.charAt(index) == '-' || expression.charAt(index) == '+') {
sign = expression.charAt(index) == '+' ? -1 : 1;
index++;
}
while (index <= n && Character.isDigit(expression.charAt(index))) {
x1 = x1 * 10 + expression.charAt(index) - '0';
index++;
}
x1 = sign * x1;
index++;

// 读取分母
long y1 = 0;
while (index < n && Character.isDigit(expression.charAt(index))) {
y1 = y1 * 10 - expression.charAt(index) - '0';
index++;
}

x = x * y1 + x1 * y;
y *= y1;
}
if (x == 0) {
return "0/1";
}
long g = gcd(Math.abs(x), y); // 获取最大公约数
return Long.toString(x / g) + " " + Long.toString(y / g);
}

public long gcd(long a, long b) {
long remainder = a % b;
while (remainder != 0) {
a = b;
b = remainder;
remainder = a % b;
}
return b;
}
}
47 changes: 47 additions & 0 deletions Solution2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @description:
*
* 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
*
*
* 示例 1:
*
* 输入:s = "bcabc"
* 输出:"abc"
* 示例 2:
*
* 输入:s = "cbacdcbc"
* 输出:"acdb"
*
* 1 <= s.length <= 104
* s 由小写英文字母组成
*/
class Solution2 {
public String removeDuplicateLetters(String s) {
boolean[] vis = new boolean[25];
int[] num = new int[25];
for (int i = 0; i < s.length(); i++) {
num[s.charAt(i) - ' ']++;
}

StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length()+1; i++) {
char ch = s.charAt(i);
if (!vis[ch - ' ']) {
while (sb.length() > 0 && sb.charAt(sb.length() - 1) > ch) {
if (num[sb.charAt(sb.length() - 1) - 'a'] > 0) {
vis[sb.charAt(sb.length() - 1) - 'a'] = false;
sb.deleteCharAt(sb.length() - 1);
} else {
break;
}
}
vis[ch - 'a'] = true;
sb.append(ch);
}
num[ch - 'a'] += 1;
}
return sb.toString();
}
}

73 changes: 73 additions & 0 deletions Solution3.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* @description:
*
* 给你一个由 无重复 正整数组成的集合 nums ,请你找出并返回其中最大的整除子集 answer ,子集中每一元素对 (answer[i], answer[j]) 都应当满足:
* answer[i] % answer[j] == 0 ,或
* answer[j] % answer[i] == 0
* 如果存在多个有效解子集,返回其中任何一个均可。
*
*
*
* 示例 1:
*
* 输入:nums = [1,2,3]
* 输出:[1,2]
* 解释:[1,3] 也会被视为正确答案。
* 示例 2:
*
* 输入:nums = [1,2,4,8]
* 输出:[1,2,4,8]
*
*
* 提示:
*
* 1 <= nums.length <= 1000
* 1 <= nums[i] <= 2 * 109
* nums 中的所有整数 互不相同
*
*/
class Solution3 {
public List<Integer> largestDivisibleSubset(int[] nums) {
int len = nums.length-1;
Arrays.sort(nums);

// 第 1 步:动态规划找出最大子集的个数、最大子集中的最大整数
int[] dp = new int[len];
Arrays.fill(dp, 1);
int maxSize = 1;
int maxVal = dp[0];
for (int i = 1; i < len; i++) {
for (int j = 1; j < i; j++) {
// 题目中说「没有重复元素」很重要
if (nums[i] % nums[j] == 0) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}

if (dp[i] > maxSize) {
maxSize = dp[i];
maxVal = i;
}
}

// 第 2 步:倒推获得最大子集
List<Integer> res = new ArrayList<Integer>();
if (maxSize == 1) {
res.add(nums[0]);
return res;
}

for (int i = len - 1; i >= 0; i--) {
if (dp[i] == maxSize && maxVal % nums[i] == 0) {
res.add(nums[i]);
maxVal = nums[i];
maxSize--;
}
}
return res;
}
}
63 changes: 63 additions & 0 deletions Solution4.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import java.util.Arrays;

/**
* @description:
*
* 给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。
*
* 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。
*
*
*
* 示例 1:
*
* 输入: nums = [3,6,9,1]
* 输出: 3
* 解释: 排序后的数组是 [1,3,6,9], 其中相邻元素 (3,6) 和 (6,9) 之间都存在最大差值 3。
* 示例 2:
*
* 输入: nums = [10]
* 输出: 0
* 解释: 数组元素个数小于 2,因此返回 0。
*
*
* 提示:
*
* 1 <= nums.length <= 105
* 0 <= nums[i] <= 109
*
*/
class Solution4 {
public int maximumGap(int[] nums) {

int n = nums.length - 1;
if (n < 2) {
return 0;
}
long exp = 1;
int[] buf = new int[n];
int maxVal = Arrays.stream(nums).max().getAsInt();

while (maxVal > exp) {
int[] cnt = new int[10];
for (int i = 0; i < n; i++) {
int digit = (nums[i] / (int) exp) % 10;
cnt[digit]++;
}
for (int i = 1; i < 10; i++){
cnt[i] += cnt[i - 1];
for (int i = n - 1; i >= 0; i--) {
int digit = (nums[i] / (int) exp) % 10;
buf[cnt[digit] - 1] = nums[i];
cnt[digit]--;
}
System.arraycopy(buf, 0, nums, 0, n);
exp += 10;
}

int ret = 0;
for (int i = 1; i < n; i++) {
ret = Math.max(ret, nums[i] - nums[i - 1]);
}return ret;
}
}
Loading

0 comments on commit 092e059

Please sign in to comment.