java基礎(10)---leetcode的String、數組以及集合的一些使用

整數

1、整數反轉_7

/*
12345  變成 54321
*/

public class 整數反轉_7 {
    public static void main(String[] args){
        int x = 12345;
        System.out.println(reverseInt(x));

    }

    public static int reverseInt(int x){
        int res = 0;
        while (x != 0){
            int pop = x % 10;
            if (res > Integer.MAX_VALUE / 10 || res == Integer.MAX_VALUE && pop > 7) return 0;
            if (res < Integer.MIN_VALUE / 10 || res == Integer.MIN_VALUE && pop < -8) return 0;
            res = res * 10 + pop;
            x /= 10;
        }
        return res;
    }
}
View Code

 

數組

1、兩數之和_1(數組)

/*
給定一個整數數組 nums 和一個目標值 target,請你在該數組中找出和爲目標值的那 兩個 整數,並返回他們的數組下標。
你能夠假設每種輸入只會對應一個答案。可是,你不能重複利用這個數組中一樣的元素。
示例:
給定 nums = [2, 7, 11, 15], target = 9
由於 nums[0] + nums[1] = 2 + 7 = 9
因此返回 [0, 1]
 */

import java.util.HashMap;
import java.util.Map;

public class 兩數之和_1 {
    public static void main(String[] args){

        int[] nums = {1,2};
        int target = 3;
        //法一:
        int[] result = method1(nums,target);
        System.out.println( result[0] + "" + result[1] );
        //法二:
        int[] result2 = method2(nums,target);
        System.out.println(result2[0] + "" + result2[1]);
    }

    //法一:兩次遍歷,時間O(n2),空間O(n)
    public static int[] method1(int[] nums, int target){
        for (int i = 0; i < nums.length; i++){
            for (int j = i+1; j < nums.length; j++){
                if (nums[i] + nums[j] == target){
                    return new int[] {i,j};
                }
            }
        }
        throw new IllegalArgumentException("No such target");
    }

    //法二:採用字典存儲,時間O(n),空間O(n)
    public static int[] method2 (int[] nums, int target){
        //遍歷一遍,存儲到map中,key爲nums值,value爲索引
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i++){
            map.put(nums[i] , i);
        }
        // 遍歷第二遍,查看target-nums[i] 是否在字典中
        for (int i = 0; i < nums.length; i++){
            int tmp = target - nums[i];
            if (map.containsKey(tmp) && map.get(tmp) != i) {
                return new int[]{i, map.get(tmp)};
            }
        }
        throw new IllegalArgumentException("No such target!");

    }

}
View Code

2、三數之和_15(數組)

/*
給定一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出全部知足條件且不重複的三元組。

注意:答案中不能夠包含重複的三元組。

例如, 給定數組 nums = [-1, 0, 1, 2, -1, -4],

知足要求的三元組集合爲:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

*/

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

public class 三數之和_15 {
    public static void main(String[] args){
        int[] nums = {-1,0,1,2,-2,4};
        threeSum(nums);
    }

    public static List<List<Integer>> threeSum(int[] nums){
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        int len = nums.length;
        if (nums == null && len < 3) return ans;
        Arrays.sort(nums); // 排序
        for (int i = 0; i < len; i++){
            if (nums[0] > 0) break; //若是第一個數大於0,直接退出
            while (i > 0 && nums[i] == nums[i-1]) continue; //去重
            int L = i+1, R = len - 1;
            while (L < R){ //兩數之和
                int sum = nums[i] + nums[L] + nums[R];
                if (sum == 0){
                    ans.add(Arrays.asList(nums[i],nums[L],nums[R]));
                    while (L < R && nums[L] == nums[L+1]) L++; //去重
                    while (L < R && nums[R] == nums[R-1]) R--; //去重
                    L++;
                    R--;
                }
                else if(sum < 0) {
                    L++;
                }
                else if (sum > 0){
                    R--;
                }
            }
        }
        return ans;

    }
}
View Code

3、刪除排序數組中的重複項_26 (數組)

/*
給定一個排序數組,你須要在原地刪除重複出現的元素,使得每一個元素只出現一次,返回移除後數組的新長度。

不要使用額外的數組空間,你必須在原地修改輸入數組並在使用 O(1) 額外空間的條件下完成。

示例 1:

給定數組 nums = [1,1,2],

函數應該返回新的長度 2, 而且原數組 nums 的前兩個元素被修改成 1, 2。

你不須要考慮數組中超出新長度後面的元素。
示例 2:

給定 nums = [0,0,1,1,1,2,2,3,3,4],

函數應該返回新的長度 5, 而且原數組 nums 的前五個元素被修改成 0, 1, 2, 3, 4。

你不須要考慮數組中超出新長度後面的元素。
 */

public class 刪除排序數組中的重複項_26 {
    public static void main(String[] args){
        int[] nums = {1,1,1,2,2,3,4,4,5};
        System.out.println(removeDulplicates(nums));
    }
    public static int removeDulplicates(int[] nums){
        if (nums.length == 0) return 0;
        int i = 0;
        for (int j = 1; j < nums.length; j++){
            if (nums[i] != nums[j]){
                i++;
                nums[i] = nums[j];
            }
        }
        return i+1;
    }
}
View Code

4、尋找兩個有序數組的中位數_4(數組)

/*
給定兩個大小爲 m 和 n 的有序數組 nums1 和 nums2。

請你找出這兩個有序數組的中位數,而且要求算法的時間複雜度爲 O(log(m + n))。

你能夠假設 nums1 和 nums2 不會同時爲空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

則中位數是 2.0
示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

則中位數是 (2 + 3)/2 = 2.5

*/

public class 尋找兩個有序數組的中位數_4 {
    public static void main(String[] arg){
        int[] nums1 = {};
        int[] nums2 = {2,3};
        System.out.println(findMedianSortedArrays(nums1,nums2));
    }

    public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int m = nums1.length;
        int n = nums2.length;

        int[] numsAll = new int[ m+n ];
        int i = 0;
        int j = 0;
        while (i < m && j < n){
            if (nums1[i] < nums2[j]){
                numsAll[i+j] = nums1[i];
                i++;
            } else{
                numsAll[i+j] = nums2[j];
                j++;
            }
        }

        for (int a=i+j; a < m+n; a++ ){
            if (i < m){
                numsAll[a] = nums1[i];
                i++;
            }
            else{
                numsAll[a] = nums2[j];
                j++;
            }
        }
        int mid = (m+n)/2;
        if ((m+n)%2 == 0){
            return (numsAll[mid-1] + numsAll[mid]) / 2.0;
        }
        else{
            return numsAll[mid];
        }

    }
}
View Code

5、搜索插入位置_35(數組)

/*
給定一個排序數組和一個目標值,在數組中找到目標值,並返回其索引。若是目標值不存在於數組中,返回它將會被按順序插入的位置。

你能夠假設數組中無重複元素。

示例 1:

輸入: [1,3,5,6], 5
輸出: 2
示例 2:

輸入: [1,3,5,6], 2
輸出: 1
示例 3:

輸入: [1,3,5,6], 7
輸出: 4
示例 4:

輸入: [1,3,5,6], 0
輸出: 0
 */
public class 搜索插入位置_35 {
    public static void main(String[] args){
        int[] nums = {1,2,5,7};
        int target = 2;
        searchInsert(nums,target);
    }

    public static int searchInsert(int[] nums, int target) {
        int len = nums.length;
        if (len <= 0) return 0;
        if (nums[len-1] < target) return len;
        int left = 0 , right = len - 1;

        while (left <= right){
            int mid = (left + right) / 2;
            if (nums[mid] > target){
                right = mid - 1;
            }
            else if (nums[mid] < target){
                left = mid + 1;
            }
            else{
                return mid;
            }
        }
        return left;

    }

}
View Code

6、楊輝三角_118 (二維數組)

import java.util.ArrayList;
import java.util.List;

public class 楊輝三角_118 {
    public static void main(String[] args){
        int numRows = 5;
        generate(numRows);

    }
    public static List<List<Integer>> generate(int numRows){
        List<List<Integer>> triangle = new ArrayList<List<Integer>> ();
        if (numRows == 0) return triangle;
        triangle.add(new ArrayList<Integer>());
        triangle.get(0).add(1);
        for (int i= 1; i < numRows; i++){
            List<Integer> row = new ArrayList<>();
            List<Integer> preRow = triangle.get(i - 1);
            row.add(1);
            for (int j = 1; j < i; j++){
                row.add(preRow.get(j) + preRow.get(j-1));
            }
            row.add(1);
            triangle.add(row);
        }
        return triangle;

    }
}
View Code

7、盛最多水的容器_11(數組)

/*
給定 n 個非負整數 a1,a2,...,an,每一個數表明座標中的一個點 (i, ai) 。在座標內畫 n 條垂直線,垂直線 i 的兩個端點分別爲 (i, ai) 和 (i, 0)。找出其中的兩條線,使得它們與 x 軸共同構成的容器能夠容納最多的水。

輸入: [1,8,6,2,5,4,8,3,7]
輸出: 49
連接:https://leetcode-cn.com/problems/container-with-most-water。
 思路:
 兩個首尾指針L,R,面積等於  高( tmp = min(nums[L],nums[R]) * 底 (R-L);
 而後,若是高等於nums[L],則L++;
 若是高等於nums[R], 則R--;

 */

public class 盛最多水的容器_11 {
    public static void main(String[] args){
        int[] height = {1,8,6,2,5,4,8,3,7};
        System.out.println(maxArea(height));
    }
    public static int maxArea(int[] height){
        int L = 0 , R = height.length - 1;
        int area = Integer.MIN_VALUE;
        while (L < R){
            int temp = Math.min(height[L] , height[R]);
            area = Math.max(area, temp * (R - L));
            if (temp == height[L]) L++;
            else if (temp == height[R]) R--;
        }
        return area;
    }

}
View Code

8、買賣股票的最佳時機_121 (數組)

/*
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。

若是你最多隻容許完成一筆交易(即買入和賣出一支股票),設計一個算法來計算你所能獲取的最大利潤。

注意你不能在買入股票前賣出股票。

示例 1:

輸入: [7,1,5,3,6,4]
輸出: 5
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。
     注意利潤不能是 7-1 = 6, 由於賣出價格須要大於買入價格。
示例 2:

輸入: [7,6,4,3,1]
輸出: 0
解釋: 在這種狀況下, 沒有交易完成, 因此最大利潤爲 0。


思路:兩個變量,一個記錄谷底數值,一個記錄結果(即最大利潤);
*/
public class 買賣股票的最佳時機_121 {
    public static void main(String[] args){
        int[] prices = {7,1,5,6,4,3};
        System.out.println(maxProfit(prices));

    }
    public static int maxProfit(int[] prices) {
        int minPrice = Integer.MAX_VALUE;
        int maxProfit = 0;
        for (int i = 0; i < prices.length; i++){
            if (prices[i] < minPrice){
                minPrice = prices[i];
            }
            else if (prices[i] - minPrice > maxProfit){
                maxProfit = prices[i] - minPrice;
            }
        }
        return maxProfit;

    }

}
View Code

 

 

字符串

1、Z型變換_6

import java.util.ArrayList;
import java.util.List;

public class Z字型變換_6 {
    public static void main(String[] args){
        String s = "leetcodeishiring";
        int numsRow = 3;
        System.out.println(convert(s,numsRow));
    }

    public static String convert(String s,int numsRow){
        if (s.length() < numsRow) return s;

        //初始化
        List<StringBuilder> rows = new ArrayList<>();
        for (int i = 0; i < Math.min(s.length(),numsRow); i++){
            rows.add(new StringBuilder());
        }

        int curRow = 0;
        boolean goingDown = false;
        for (char c:s.toCharArray()){
            rows.get(curRow).append(c);
            if (curRow == 0 || curRow == numsRow - 1) goingDown = !goingDown;
            curRow += goingDown ? 1 : -1;
        }

        StringBuilder res = new StringBuilder();
        for (StringBuilder row: rows){
            res.append(row);
        }
        return res.toString();

    }

}
View Code

2、二進制求和_67

/*
1011 + 1101 = 11000
*/
public class 二進制求和_67 {
    public static void main(String[] args){
        String a = "1011", b = "1101";
        System.out.println(addBinary(a,b));

    }
    public static String addBinary(String a,String b){
        StringBuilder ans = new StringBuilder();
        int ca = 0;
        for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--){
            int sum = ca;
            sum += (i >= 0) ? a.charAt(i) - '0' : 0;
            sum += (j >= 0) ? b.charAt(j) - '0' : 0;
            ca = sum / 2;
            ans.append(sum % 2);
        }
        ans.append(ca == 1 ? ca : "");
        return ans.reverse().toString();
    }
}
View Code

3、惟一摩爾斯密碼詞_804

import java.util.HashMap;
import java.util.Map;

public class 惟一摩爾斯密碼詞_804 {
    public static void main(String[] args) {
        String[] pwd = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."};
        String keys = "abcdefghijklmnopqrstuvwxyz";
        char[] key = keys.toCharArray();
        Map<String, Integer> map = new HashMap<>();

        String[] words = {"gin", "zen", "gig", "msg"};
        for (String word : words) {
            String password = "";
            for (char ch : word.toCharArray()) {
                password += pwd[ch - 97];
            }
            map.put(password, 1);
        }
        System.out.println(map.keySet().size());
    }
}
View Code

4、報數_38

/*
1  1 
2  11 "一個1"
3  21 "一個2一個1"
4  1211 "一個2一個1"
5  111221 "一個1一個2兩個1"
6  312211
 */
public class 報數_38 {
    public static void main(String[] args){
        int n = 4;
        System.out.println(
                countAndSay(n)
        );

    }
    public static String countAndSay(int n) {
        String s = "11";
        if (n==1){
            return "1";
        } else if(n==2){
            return s;
        }

        for (int i = 2; i < n; i++ ){
            int j = 0;
            StringBuilder num = new StringBuilder();

            while (j < s.length()-1){
                int count = 1;
                while (j < s.length()-1 && s.charAt(j) == s.charAt(j+1)){
                    count += 1;
                    j++;
                }
                num.append(""+count).append(s.charAt(j));
                j++;
            }
            if (s.charAt(s.length()-1) != s.charAt(s.length()-2) ){
                num.append("1").append(s.charAt(s.length()-1));
            }
            s = num.toString();

        }
        return s;

    }
}
View Code

5、無重複的最長子串_3

/*
給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。

示例 1:

輸入: "abcabcbb"
輸出: 3
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3。
示例 2:

輸入: "bbbbb"
輸出: 1
解釋: 由於無重複字符的最長子串是 "b",因此其長度爲 1。
示例 3:

輸入: "pwwkew"
輸出: 3
解釋: 由於無重複字符的最長子串是 "wke",因此其長度爲 3。
     請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。
 */

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class 無重複元素的最長子串_3 {
    public static void main(String[] args){
        String s = "dvdf";
        int res = lengthOfLongestSubstring(s);
        System.out.println(res);
    }

    public static int lengthOfLongestSubstring(String s) {
        Map<Character,Integer> map = new HashMap<> ();
        int start = -1;
        int res = 0;
        for (int i = 0; i < s.length(); i++){
            if (map.containsKey(s.charAt(i))){
                start = Math.max(start,map.get(s.charAt(i)));
            }
            res = Math.max(i - start,res);
            map.put(s.charAt(i),i);

        }
        return res;
    }
}
View Code

6、轉換成小寫字母_709

/*
全部字符串都轉成小寫
 */
public class 轉換成小寫字母_709 {
    public static void main(String[] args){
        String s = "HeLLo";
        System.out.println(toLowerCase(s));
    }

    public static String toLowerCase(String str){
        char[] cArray = str.toCharArray();
        for(int i= 0; i<cArray.length; i++){
            if (cArray[i] <= 'Z' && cArray[i]>='A') {
                cArray[i] = (char) (cArray[i] + 32);
            }
        }
        return String.valueOf(cArray);
    }
}
View Code

7、驗證迴文串_125

/*
給定一個字符串,驗證它是不是迴文串,只考慮字母和數字字符,能夠忽略字母的大小寫。

說明:本題中,咱們將空字符串定義爲有效的迴文串。

示例 1:

輸入: "A man, a plan, a canal: Panama"
輸出: true
示例 2:

輸入: "race a car"
輸出: false
 */
public class 驗證迴文串_125 {

    public static void main(String[] args){
        String s = "A man, a plan, a canal:Panama";
        System.out.println(isPal1(s));

    }

    public static boolean isPal1(String s){
        int len = s.length();
        s = s.toLowerCase();
        int i = 0, j = len - 1;
        while (i < j){
            while (!isAlpha(s.charAt(i))){
                i++;
                if (i == len){
                    return true;
                }
            }
            while (!isAlpha(s.charAt(j))){
                j--;
            }
            if (s.charAt(i)!= s.charAt(j)){
                return false;
            }
            i++;
            j--;
        }
        return true;
    }

    public static boolean isAlpha(char c){
        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' &&c <= '9')){
            return true;
        }
        return false;
    }
}
View Code

 

 

HashMap

1、有效的括號_20

/*
判斷括號是否有效
 */
import javax.swing.text.html.ListView;
import java.util.HashMap;
import java.util.Stack;

public class 有效的括號_20 {
    private HashMap<Character,Character> mapping;
    public 有效的括號_20(){
        this.mapping = new HashMap<Character, Character>();
        this.mapping.put(')','(');
        this.mapping.put(']','[');
        this.mapping.put('}','{');
    }
    public static void main(String[] args){
        String s = "(()[])";
        有效的括號_20 res = new 有效的括號_20();
        System.out.println(res.isValid(s));


    }
    public boolean isValid(String s){
        Stack<Character> stack = new Stack<>();
        for (char ch : s.toCharArray()){
            if (this.mapping.containsKey(ch)) {
                char popChar = stack.isEmpty() ? '#' : stack.pop();
                if (popChar != this.mapping.get(ch)) {
                    return false;
                }
            } else {
                    stack.push(ch);
            }
        }
        return stack.isEmpty();
    }
}
View Code

 

 

HashSet

1、兩個數組的交集_349

/*
給定兩個數組,編寫一個函數來計算它們的交集。

示例 1:

輸入: nums1 = [1,2,2,1], nums2 = [2,2]
輸出: [2]
示例 2:

輸入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
輸出: [9,4]
 */

import java.util.Arrays;
import java.util.HashSet;
public class 兩個數組的交集_349 {
    public static void main(String[] args){
        int[] nums1 = {4,9,5};
        int[] nums2 = {9,4,9,8,4};
        intersection(nums1, nums2);

    }

    public static int[] intersection(int[] nums1, int[] nums2) {
        HashSet<Integer> set1 = new HashSet<>();
        for (Integer i: nums1) set1.add(i);
        HashSet<Integer> set2 = new HashSet<>();
        for (Integer i : nums2) set2.add(i);


        if (set1.size() < set2.size())  return helper(set1 ,set2);
        else return helper(set2,set1);

    }

    public static int[] helper(HashSet<Integer> set1 , HashSet<Integer> set2){
        int[] ans = new int[set1.size()];
        int idx = 0;
        set1.retainAll(set2);
        for (int i : set1){
            ans[idx++] = i;
        }
        return Arrays.copyOf(ans,idx);

    }
}
View Code

 2、獨一無二的出現次數_1207

    public boolean uniqueOccurrences(int[] arr) {
        HashMap <Integer,Integer> map = new HashMap<>();
        for (int i:arr){
            if (map.containsKey(i)){
                map.put(i,map.get(i)+1); 
            }else{
                map.put(i,1);
            }
        }
        Set<Integer> set = new HashSet<> ();
        for (int i : map.values()){
            set.add(i);
        }
        return map.size() == set.size();
    }
View Code

 

 

鏈表

1、兩數相加_2

/*
給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,而且它們的每一個節點只能存儲 一位 數字。

若是,咱們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。

您能夠假設除了數字 0 以外,這兩個數都不會以 0 開頭。

示例:

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
緣由:342 + 465 = 807
 */

import java.util.ArrayList;
class ListNode{
    int val;
    ListNode next;
    ListNode(int x){ val = x; }
}

public class 兩數相加_2 {
    public static void main(String[] args) {
        ListNode l1 = new ListNode(1);
        ListNode head1 = l1;
        for (int i = 2; i < 5; i++){
            l1.next = new ListNode(i);
            l1 = l1.next;
        }
        ListNode l2 = new ListNode(3);
        ListNode head2 = l2;
        for (int i = 4; i < 6; i++){
            l2.next = new ListNode(i);
            l2 = l2.next;
        }
        ArrayList<Integer> list = new ArrayList<Integer> ();
        ListNode res = addNum(head1,head2);
        while (res != null){
            list.add(res.val);
            res = res.next;
        }
        list.stream().forEach(System.out::println);
    }

    public static ListNode addNum (ListNode l1 , ListNode l2){
        ListNode res = new ListNode(0);
        ListNode head = res;
        int flag = 0;
        while (l1 != null || l2 != null){
            int x = (l1 != null) ? l1.val : 0;
            int y = (l2 != null) ? l2.val : 0;
            int sum = x + y + flag;
            flag = sum / 10;
            res.next = new ListNode(sum % 10);
            res = res.next;
            if (l1 != null) l1 = l1.next;
            if (l2 != null) l2 = l2.next;
        }

        if (flag > 0){
            res.next = new ListNode(flag);
        }
        return head.next;
    }
}
View Code
相關文章
相關標籤/搜索