(Java版)leetcode
注:1、38、53、58、66、67、69
1. 两数之和
- 题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
- 代码
class Solution{
public static int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i],i);
}
for (int i = 0; i < nums.length; i++) {
int fit = target - nums[i];
if (map.containsKey(fit) && map.get(fit) != i){
return new int[] {i, map.get(fit)};
}
}
throw new IllegalArgumentException("NO TWO SUM SOLUTION");
}
public static void main(String []args){
//Solution test = new Solution();
int nums[]={2,7,8,9};
int target = 9;
System.out.println(Arrays.toString(twoSum(nums,target)));
}
}
# 方法二 只用一个for循环
class Solution{
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int fit = target - nums[i];
if(map.containsKey(fit) && map.get(fit) != i)
return new int[] {map.get(fit), i};
map.put(nums[i],i);
}
throw new IllegalArgumentException("NO TWO SUM SOLUTION");
}
}
38.报数
- 题目描述
报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1
11
21
1211
111221
注意:整数顺序将表示为一个字符串。
- 代码
方法一:
package practice1;
import org.junit.Test;
// 方法一 : 使用String
public class Count_and_Say {
public static String test(String str) {
String str_end = "";
int i = 0;
while(i<str.length()) {
char now = str.charAt(i);
int num = 1;
for(int j=i+1; j<str.length(); j++) {
if(now != str.charAt(j)) {
break;
}
num++;
}
//System.out.println(num);
i += num;
str_end += (String.valueOf(num) + now);
}
return str_end;
}
public static String test2(int n) {
String str="1";
if(n == 1) {
return str;
}
for(int i=2; i<=n; i++) {
str = test(str);
}
return str;
}
public static void main(String[] args) {
System.out.println(test2(5));
}
}
方法二
package practice1;
import org.junit.Test;
// 方法二 : 使用StringBuffer
public class Count_and_Say {
public static String test(String str) {
//String str_end = "";
StringBuffer str_end = new StringBuffer();
int i = 0;
while(i<str.length()) {
char now = str.charAt(i);
int num = 1;
for(int j=i+1; j<str.length(); j++) {
if(now != str.charAt(j)) {
break;
}
num++;
}
//System.out.println(num);
i += num;
str_end.append(String.valueOf(num)).append(now);
}
return str_end.toString();
}
public static String test2(int n) {
String str="1";
if(n == 1) {
return str;
}
for(int i=2; i<=n; i++) {
str = test(str);
}
return str;
}
public static void main(String[] args) {
System.out.println(test2(5));
}
}
53. 最大子序和
- 题目描述
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
- 代码
//方法一:双层for循环
public int maxSubArray(int[] nums) {
int max = nums[0];
for(int i=0; i<nums.length; i++) {
int sum = nums[i];
if(sum > max) {
max = sum;
}
for(int j=i+1; j<nums.length; j++) {
sum += nums[j];
if(sum>max) {
max = sum;
}
}
}
return max;
}
//方法二
public int maxSubArray(int[] nums) {
int max = nums[0];
int sum = 0;
for(int num : nums) {
if(sum<0) {
sum = num;
}
else {
sum += num;
}
max = Math.max(sum, max);
}
return max;
}
58. Length of Last Word
- 题目描述
给定一个仅包含大小写字母和空格 ’ ’ 的字符串,返回其最后一个单词的长度。
如果不存在最后一个单词,请返回 0 。
说明:一个单词是指由字母组成,但不包含任何空格的字符串。
示例:
输入: “Hello World”
输出: 5
- 代码描述
class Solution {
public int lengthOfLastWord(String s) {
String s_t = s.trim();
if(s.isEmpty() || s_t.isEmpty()) {
return 0;
}
char[] s1 = s_t.toCharArray();
int count = 0;
for (int i = s1.length-1; i>=0; i--) {
char l = s1[i];
if(l == ' ') {
break;
}
count++;
}
return count;
}
}
class Solution {
public int lengthOfLastWord(String s) {
String s_t = s.trim();
if(s.isEmpty() || s_t.isEmpty()) {
return 0;
}
int count = 0;
for (int i = s_t.length()-1; i>=0; i--) {
char l = s_t.charAt(i);
if(l == ' ') {
break;
}
count++;
}
return count;
}
}
66. Plus-one
- 题目描述
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
- 代码描述
class Solution {
public int[] plusOne(int[] digits) {
for(int i = digits.length-1; i>=0; i--){
digits[i] ++;
if(digits[i] == 10){
digits[i] = 0;
}else{
return digits;
}
}
int[] ans = new int[digits.length+1];
System.arraycopy(digits, 0, ans, 1, digits.length);
ans[0] = 1;
return ans;
}
}
67. add-binary
- 题目描述
给定两个二进制字符串,返回他们的和(用二进制表示)。
输入为非空字符串且只包含数字 1 和 0。
示例 1:
输入: a = “11”, b = “1”
输出: “100”
示例 2:
输入: a = “1010”, b = “1011”
输出: “10101”
- 代码描述
方法一
# 总体思路是,将两个字符串反转,让a始终是长度最大的那一个,按照a的长度进行循环。
1) 当前位和 add
b长度不够时,就默认该位和 a[i]+进位,否则就时a[i]+b[i]+进位;
2) 判断是否有进位 push
如果add>=2,说明有进位,此时add -= 2,且push=1;否则无进位push=0;
3) 最后如果有进位,记得加上,然后进行反转
class Solution {
public String addBinary(String a, String b) {
StringBuffer result = new StringBuffer();;
int add = 0;
int push = 0;
//a始终是最长的
if(a.length() <= b.length()) {
String tmp = null;
tmp = a;
a = b;
b = tmp;
}
a = new StringBuffer(a).reverse().toString();
b = new StringBuffer(b).reverse().toString();
for(int i=0; i<a.length(); i++) {
if(i>b.length()-1) {
add = a.charAt(i)-'0'+ push;
}else {
add = a.charAt(i)-'0' + b.charAt(i) - '0' + push;
}
if(add >=2) {
add -= 2;
push = 1;
}else {
push = 0;
}
result = result.append(add);
}
//如果有进位
if(push == 1) {
result = result.append(push);
}
return result.reverse().toString();
}
}
方法二
# 这个就是a b不用仅从反转,不用在之前就判断谁最长
class Solution {
public String addBinary(String a, String b) {
int push = 0;
StringBuffer result = new StringBuffer();
for(int i=a.length()-1,j=b.length()-1; i>=0 || j>=0; i--,j--) {
int add = 0;
add += i >= 0 ? a.charAt(i) - '0' : 0;
add += j >= 0 ? b.charAt(j) - '0' : 0;
add += push;
if(add >= 2) {
add -= 2;
push = 1;
}else {
push = 0;
}
result.append(add);
}
if(push == 1) {
result.append(1);
}
return result.reverse().toString();
}
}
69. sqrtx
- 题目描述
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842…,
由于返回类型是整数,小数部分将被舍去
- 代码描述
方法一
# 利用二分查找法,如果大于4的时候平方肯定小于等于它的一半;i和j分别代表左右的指针。
class Solution {
public int mySqrt(int x) {
long mid; //注意用的是long因为想耨写数据不能通过如2147395599
long i=0, j=x;
if(x>=4) {
j=x/2;
}
while ((i-j)<=0) {
mid =(i + j) / 2;
if ((mid * mid) > x) {
j = mid - 1;
} else if((mid * mid) < x) {
i = mid + 1;
}else {
return (int)mid;
}
}
return (int)j;
}
}
方法二
# 牛顿迭代法
class Solution {
public int mySqrt(int x) {
long res = 1;
while(true) {
res = (res + x/res)/2;
if((res*res-x)<1e-10) {
return (int)res;
}
}
}
}
方法三
# 和方法二是一样的只不过从后往前,因为大于4的时候,它的解就小于等于它的一半,所以这个比方法二慢一点
class Solution {
public int mySqrt(int x) {
long res = x;
while(x<res*res) {
res = (res + x/res)/2;
}
return (int)res;
}
}