Leecode算法题(Java)
1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。来源:力扣(LeetCode)
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
题解:
class Solution {
public int[] twoSum(int[] nums, int target) {
int len =nums.length;
for(int i=0;i<len-1;i++){
for(int j=i+1;j<len;j++){
if(nums[i]+nums[j]==target){
return new int[] {i,j};//这里是Java中返回int型数组的方法
}
}
}
return null;//这里要特别注意
}
}
2.给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
题解:
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int sum = 0;//进行链表对应位置的每一步计算
ListNode first = new ListNode(0);//新建一个初值为0的链表
ListNode t=l1;//指向链表1
ListNode p=l2;//指向链表2
ListNode cur = first;//新建一个指针,指向first链表
while(t!=null || p!=null){
if(t!=null){
sum+=t.val;//sum将该t位置的val(int)值,添加进去
t=t.next;
}
if(p!=null){
sum+=p.val;//sum将该p位置的val(int)值,添加进去
p=p.next;
}
cur.next=new ListNode(sum%10);//下一结点的数值为sum%10
cur=cur.next;//再次指向cur指针的下一结点,也可以说指向cur指针标记first链表位置的,下一first位置
sum=sum/10;//sum除10,结果作为下一sum的起始数值
}
if(sum>0){
cur.next=new ListNode(1);//如果遍历到最后,sum还不为0,则说明最后一位进位了,因此,再次开辟空间,给新的空间赋值1。
}
return first.next;//该位置是.next的原因:因为新建first链表时,给first的初位置赋值为0,而从未对该位置进行操作,因此,当返回结果数值时,应该从first链表的第二位开始返回。
}
}
3.给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
题解:
package leecode_Test;
import java.util.Scanner;
public class test1 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String str = sc.next();
System.out.println(lengthOfLongestSubstring(str));
}
public static int lengthOfLongestSubstring(String s) {
int i = 0;
int flag = 0;
int length = 0;
int result = 0;
while (i < s.length()) {
int pos = s.indexOf(s.charAt(i),flag);//indexOf作用:第一个参数:指定的变量。第二个参数:指定的位置
if (pos < i) {//证明存在重复字符
if (length > result) {
result = length;//result应该是记录最大不重复的字符串长度
}
if (result >= s.length() - pos - 1) {
return result;//该步的作用是:如果记录的最大长度(result)大于等于后续剩余字符长度,那么,就说明,result已为最大字符长度,则直接返回result结果
}
length = i - pos - 1;//取两个重复字符中间的字符个数,而减一的目的是为了:让辨别结点从第一位重复元素的下一位开始识别
flag = pos + 1;//记录第一位重复字符的下一位的位置
}
length++;//该步length可以自然自增的原因是:1、当有重复字符时,上一步length是两个重复字符的中间字符个数,但是,仔细考虑
//中间字符应该为每个独立,各不相同,因此,将前面的重复字符去掉后,后面的重复字符又补了进来,所以,length的值应该自增加一
i++;//向下依次遍历字符串中的字符
}
return length;//考虑字符串内没有重复字符,做的预处理
}
}
7.给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
题解:
package leecode_Test;
import java.util.Scanner;
public class test5 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int num =sc.nextInt();
System.out.println(reverse(num));
//Java中int类整数的最大值是:2的31次方-1
//最大值:2147483647
//最小值:-2147483648
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
public static int reverse(int x) {
long y = 0;
while (x != 0) {
y = y * 10 + x % 10;
x /= 10;
}
if (y > Integer.MAX_VALUE || y < Integer.MIN_VALUE)
return 0;
return (int) y;
}
}
13.罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class test13_1 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String string = sc.next();
System.out.println(method(string));
}
public static int method(String s){
Map<String,Integer> map = new HashMap<>();
map.put("I",1);
map.put("IV",4);
map.put("V",5);
map.put("IX",9);
map.put("X",10);
map.put("XL",40);
map.put("L",50);
map.put("XC",90);
map.put("C",100);
map.put("CD",400);
map.put("D",500);
map.put("CM",900);
map.put("M",1000);
int num=0;
for(int i=0;i<s.length();){
if(i+1<s.length()&&map.containsKey(s.substring(i,i+2))){
num+=map.get(s.substring(i,i+2));
i+=2;
}else{
num+=map.get(s.substring(i,i+1));
i++;
}
}
return num;
}
}
14.编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”
示例 2:
输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
public class test14 {
public static void main(String[] args){
String[] strings = new String[5];
Scanner sc = new Scanner(System.in);
strings[0]=sc.next();
strings[1]=sc.next();
strings[2]=sc.next();
strings[3]=sc.next();
strings[4]=sc.next();
System.out.println(longestCommonPrefix(strings));
}
public static String longestCommonPrefix(String[] strs) {
if(strs.length==0 || strs==null){
return "";
}
for(int i=0;i<strs[0].length();i++){
char c = strs[0].charAt(i);
for(int j=1;j<strs.length;j++){
if(i==strs[j].length() || strs[j].charAt(i)!=c ){
return strs[0].substring(0,i);
}
}
}
return strs[0];
}
}
思路:
该题算法是:以第一个字符串为基础,用以与其他字符串进行比较,获得公共前缀,返回结果为第一个字符串的截取结果。
21.将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
题解:
public class test21_3 {//利用递归的方法
public class ListNode{
int val;
ListNode next;
ListNode(int x){
val = x;
}
}
public static ListNode merge(ListNode l1,ListNode l2){
if(l1==null){//若l1为空则返回l2
return l2;
}
else if(l2==null){//若l2为空则返回l1
return l1;
}
else if(l1.val<l2.val){
l1.next=merge(l1.next,l2);
return l1;
}
else{
l2.next=merge(l1,l2.next);
return l2;
}
}
}
思路:
链表l1:1->3
链表l2:2->4
为例
首先:l1:1->
l2:2->
l1:3->
l2:4
最后,由于l1中数据已空,则返回4到l1的3->4中,然后3->4返回到l2中,2->3->4,最后,返回到l1中,1->2->3->4。如果没有看懂的话,可以用1,2,3,4,自己试一下。
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例1:
输入: haystack = “hello”, needle = “ll”
输出: 2
示例2:
输入: haystack = “aaaaa”, needle = “bba”
输出: -1
题解:
import java.util.Scanner;
public class test_28 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String str1 = sc.next();
String str2 = sc.next();
System.out.println(strStr(str1,str2));
}
public static int strStr(String haystack, String needle) {
int strLen = haystack.length(), subLen = needle.length();
if (subLen == 0) return 0;
if (strLen == 0) return -1;
// 构建状态机
int[][] FSM = new int[subLen][256];
int X = 0, match = 0;
for (int i = 0; i < subLen; i++) {
match = (int) needle.charAt(i);
for (int j = 0; j < 256; j++) {
// 当前状态 + 匹配失败字符 = 孪生词缀状态 + 匹配字符
FSM[i][j] = FSM[X][j];
}
FSM[i][match] = i + 1;
if (i > 1) {
// 下一孪生前缀状态 = X + match
X = FSM[X][match];
}
}
// 匹配子串
int state = 0;
for (int i = 0; i < strLen; i++) {
state = FSM[state][haystack.charAt(i)];
if (state == subLen) {
return i - subLen + 1;
}
}
return -1;
}
}