1--10 leetcodeJAVA 刷题

1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for (int i = 0; i <nums.length ; i++){
            for(int j=i+1; j<nums.length ; j++){
                if(target-nums[i]==nums[j]){
                    return new int[] {i,j};
                }
            }
        }
    throw new IllegalArgumentException("no two sum solution");    
    }
}

暴力破解: 注意事项:1. return new int[] {i,j}; 应该是一个数组的形式。 最后如果失败应该是 throw new IllegalArgumentException(“no two sum solution”); 表明向方法传递了一个不合法或不正确的参数

map集合总结:
1.是一个双列集合,(一个key ,一个value)
2. key 和value 的数据结构可以相同也可以不同。
3. key 不允许重复,value 可以重复。
HashMap
1.无序的集合
4. LinkHashMap 是有序的集合
1--10 leetcodeJAVA 刷题_第1张图片
1--10 leetcodeJAVA 刷题_第2张图片

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map = new HashMap();
        for(int i=0; i< nums.length ; i++){
            int complemnt = target - nums[i];
            if(map.containsKey(complemnt)){
                return new int[] {map.get(complemnt),i};
            }
            map.put(nums[i],i);
        }
        throw new IllegalArgumentException("no two sum solution");
    }
}

最简单的解题方式: 在往map里面装的时候,就要判断 Map 里面有没有符合的数。
注意:不能写反,关键字 contionsKey是判断有没有包含这个数字,get 是获取这个key的value。
1--10 leetcodeJAVA 刷题_第3张图片
2.给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode l3 = new ListNode(0);
        ListNode p1 = l1, p2 = l2, p3 = l3;
        int carry =0;
        while(p1 != null || p2 != null){
            int x = (p1 != null)? p1.val:0;
            int y = (p2 != null)?p2.val:0;
            int sum = carry+x+y;
            carry = sum /10;
            p3.next= new ListNode(sum%10);
            p3=p3.next;
            if(p1!=null) p1=p1.next;
            if(p2!=null) p2=p2.next;
        }
        if(carry>0){
            p3.next = new ListNode(carry);
        }  
        return l3.next;
    }
}

解题: 建立一个链表,和C语言的指针是一样的。其中的关键最后return l3.next; 因为在刚建立的时候的节点是0 ,所有返回的时候要变成next;

**3.**给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:

输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int end = 0, start = 0; end < n; end++) {
            char alpha = s.charAt(end);
            if (map.containsKey(alpha)) {
                start = Math.max(map.get(alpha), start);
            }
            ans = Math.max(ans, end - start + 1);
            map.put(s.charAt(end), end + 1);
        }
        return ans;
    }
}

注意事项:1. Map map = new HashMap<>(); 其中不同的则不同,则要加new HashMap<>
2.其中加入了散列表,和滑动窗口。
3.值得注意的是:其中的ans 只要记录最大的就可以、
4.start = Math.max(map.get(alpha), start); 是找到了start 以前的也不会改变start.

4.给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if(nums1==null||nums1.length==0){
            int length = nums2.length;
            int middle = length / 2;
            if(length % 2 != 0){
                return nums2[middle];
            }else{
                return (nums2[middle]+nums2[middle-1])/2.0;
            }
        }
        if(nums2==null||nums2.length==0){
            int length = nums1.length;
            int middle = length/2;
            if(length % 2 != 0){
                return nums1[middle];
            }else{
                return (nums1[middle]+nums1[middle-1])/2.0;
            }
        }
        int i1 = 0;
        int i2 = 0;
        int last =0;
        int current=0;
        int l1 = nums1.length;
        int l2 = nums2.length;
        int sum = l1+l2;
        int middle = sum /2;
        int index =0;
        while(index <= middle){
            index++;
            last = current;
            if (i2 == l2) {
                current = nums1[i1];
                i1++;
                continue;
            }
            if (i1 == l1) {
                current = nums2[i2];
                i2++;
                continue;
            }
            if (nums1[i1]<=nums2[i2]){
                current = nums1[i1];
                i1++;    
            }else{
                current = nums2[i2];
                i2++;
            }
            
        }
        if(sum%2==0){
            return (last+current)/2.0;
        }else{
            return current;
        }
    }
}

本次的代码是按着自己的思路写出来的,应该坚持自己的思路来写,而不是看别人的代码,思路也是非常的简单,就是参数非常 的多,但是是符合题目要求的。

5 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        if(len<2){
            return s;
        }
        int maxLen = 1;
        String res = s.substring(0,1);
        for(int i =0; i<len-1; i++){
            for(int j=i+1;j<len ;j++){
                if(j-i+1>maxLen&& huiwen(s,i,j)){
                    maxLen=j-i+1;
                    res = s.substring(i,j+1);
                }
            }
        }
        return res;

    }
    private boolean huiwen(String s, int left,int right){
        while(left<right){
             if(s.charAt(left) != s.charAt(right)){
            return false;
            }
            left++;
            right--;            
        }
        return true;       
    }
    
}

此方法是暴力破解方法,运用了两个for 循环,第一个for指定起始位置,第二个for 是指定了substring 的范围,然后写一个方法,调用huiwen 方法,回文方法是从两端开始,进行对比,如果对比不对,就会返回false. 这是暴力破解的方法。
**易错点:**if(s.charAt(left) != s.charAt(right))
暴力法采用双指针两边夹,验证是否是回文子串。

第二种方法:动态规划:

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        if(len < 2 ){
            return s;
        }
        int currlen=0;
        int start=0;
        int maxlen=1;
        Boolean[][] dp = new Boolean[len][len];
        for(int i =0; i<len ;i++){
            dp[i][i]=true;
        }
        for( int j=1; j<len ; j++){
            for(int i=0; i<j; i++){
                if(s.charAt(i)==s.charAt(j)){
                    if(j-i<3){
                         dp[i][j]=true;
                    }else{
                        dp[i][j]=dp[i+1][j-1];
                    }
                }else{
                     dp[i][j]=false;
                }
                if(dp[i][j]){
                    currlen = j-i+1;
                    if(currlen>maxlen){
                        start=i;
                        maxlen = currlen;
                    }
                }
            }
        }
        return s.substring(start, start+maxlen);
    }
}

注意事项;动态规划就是建表,j 和 i 相当于圈定了范围,然后就是在重复上一次的执行过程,过程是自底向下的,然后在一次的比较就可以。

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

比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:

L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。

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

string convert(string s, int numRows);
示例 1:

输入: s = “LEETCODEISHIRING”, numRows = 3
输出: “LCIRETOESIIGEDHN”
示例 2:

输入: s = “LEETCODEISHIRING”, numRows = 4
输出: “LDREOEIIECIHNTSG”
解释:

L D R
E O E I I
E C I H N
T S G

1--10 leetcodeJAVA 刷题_第4张图片

class Solution {
    public String convert(String s, int numRows) {
        if(numRows<2){
            return s;
        }
        List<StringBuilder> rows = new ArrayList<StringBuilder>();
        for(int i =0; i<numRows; i++)rows.add(new StringBuilder());
        int i=0;
        int flag=-1;
        for(char c :s.toCharArray()){
            rows.get(i).append(c);
            if(i==0||i==numRows-1)  flag= -flag;
            i+=flag;
        }
        StringBuilder res = new StringBuilder();
        for(StringBuilder row: rows)res.append(row);
        return res.toString();
    }
}

注意事项: 这个flag 用的太秀了,就像可以 摆动的旗子,可以进行来回的摆动,并且在ArrayList 里面建立的字符串数组,真的是很强,字符串数组的编号等。其实写程序的过程也是在往数据里面写的过程。

7.
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:

输入: 123
输出: 321

class Solution {
    public int reverse(int x) {
        long n=0;
        while(x !=0){
            n= n*10+x%10;
            x = x/10;
        }
        return (int)n==n? (int)n:0;
    }
}

最简单的数字的翻转。

常见知识点:
s.toCharArray() 将字符串转换为字符数组
1--10 leetcodeJAVA 刷题_第5张图片
1--10 leetcodeJAVA 刷题_第6张图片
1--10 leetcodeJAVA 刷题_第7张图片
第二种解法:

class Solution {
    public int reverse(int x) {
        String a = Integer.toString(x);
        int b=1;
         if(a.charAt(0) == '-') {
        a = a.substring(1);
        b = -1;
        }
        char[] chars = a.toCharArray();
        char[] chars1 = new char[chars.length];
        for (int i = chars.length - 1; i >= 0; i--) {
        chars1[chars.length - 1 - i] = chars[i];
    }

    Long along = Long.valueOf(new String(chars1));
    if(along>Integer.MAX_VALUE||along<Integer.MIN_VALUE){
        return 0;
    }
    return (int)(along*b);
    }
}

其中最重要的是里面的对,字符转换为字符串, 在由字符串转换为数字的过程。
String a = Integer.toString(x); //把数字转换为字符串
a.charAt(0) == ‘-’ // 字符串可以拿出任意位置的字符
char[] chars = a.toCharArray(); // 转换为字符串数组
Long along = Long.valueOf(new String(chars1)); //先建立字符串,然后转化为long 值。
其中 long string array 三者的转换的中间量是string

你可能感兴趣的:(刷题)