1. 程式人生 > 其它 >【劍指 Offer】3~10

【劍指 Offer】3~10

技術標籤:Java Program連結串列字串java資料結構

文章目錄


3、陣列中重複的數字

找出陣列中重複的數字

在一個長度為 n 的陣列 nums 裡的所有數字都在 0~n-1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意一個重複的數字。

示例1:

輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3 

限制:

2 <= n <= 100000

解析:

從頭掃描陣列,一個蘿蔔一個坑,遇到下標為i的數字如果不是i的話,(假設數字為m),那麼我們就拿與下標m的數字交換,直到交換到下標i的數字也是i為止。交換期間,如果下標為i的數字等於下標為m的數字,那就返回該數字,即找到重複數字。

class Solution {
    public int findRepeatNumber(int[] nums) {
        int temp;
        for(int i=0;i<nums.length;i++){
            while(nums[i]!=i){
                if(nums[i]==nums[nums[i]]){
                    return nums[i];
                }
                temp = nums[i];
                nums[
i] = nums[temp]; nums[temp] = temp; } } return -1; } }

4、二維陣列中的查詢

在一個 n * m 的二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個高效的函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。

示例 1:

現有矩陣 matrix 如下:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16,
22], [10, 13, 14, 17, 24], [18, 21, 23, 26, 30] ]

給定 target = 5,返回 true。

給定 target = 20,返回 false。

限制:

0 <= n <= 1000
0 <= m <= 1000

解析:

    class Solution {
        public boolean findNumberIn2DArray(int[][] matrix, int target) {
            if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
                return false;
            }

            int row = 0;
            int col = matrix[0].length - 1;
            while (row <= matrix.length - 1 && col >= 0) {
                if (target > matrix[row][col]) {
                    row++;
                } else if (target < matrix[row][col]) {
                    col--;
                } else {
                    return true;
                }
            }
            return false;
        }
    }

5、替換空格

請實現一個函式,把字串 s 中的每個空格替換成"%20"。

示例 1:

輸入:s = "We are happy."
輸出:"We%20are%20happy."

限制:

0 <= s 的長度 <= 10000

解析:

方法一:遍歷 + 快取

class Solution {
    public String replaceSpace(String s) {
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<s.length(); i++){
            if(s.charAt(i) == ' '){
                sb.append("%20");
            }else {
                sb.append(s.charAt(i));
            }
        }
        return sb.toString();
    }
}

方法二:呼叫api介面

class Solution {
    public String replaceSpace(String s) {
        return s.replaceAll(" ","%20");
    }
}

方法三:遍歷 + 字元陣列

由於空格要替換為%20,那麼,可以宣告一個字元陣列,大小是字串的3倍。依次遍歷字串,逐漸將字元填入字元陣列之中,當遇到空格時,變為新增%、2、0三個字元。最後,生成新的字串,擷取字元陣列中有效的部分即可,即字元陣列從0開始,長度為有效儲存進字元陣列的長度。

class Solution {
    public String replaceSpace(String s) {

        char[] ch = new char[s.length() * 3];
        int index = 0;
        for(int i=0; i<s.length(); i++){
            char c = s.charAt(i);
            if(c == ' '){
                ch[index++] = '%';
                ch[index++] = '2';
                ch[index++] = '0';
            }else {
                ch[index++] = c;
            }
        }
        return new String(ch, 0, index);
    }
}

6、從尾到頭列印連結串列

輸入一個連結串列的頭節點,從尾到頭反過來返回每個節點的值(用陣列返回)。

示例 1:

輸入:head = [1,3,2]
輸出:[2,3,1]

限制:

0 <= 連結串列長度 <= 10000

解析:

方法一:遞迴

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    ArrayList<Integer> temp = new ArrayList<Integer>();
    public int[] reversePrint(ListNode head) {
        reverse(head);
        int [] arr = new int [temp.size()];
        for(int i=0;i<arr.length;i++){
            arr[i]=temp.get(i);
        }
        return arr;
    }

    public void reverse(ListNode head){
        if(head==null){
            return;
        }
        reverse(head.next);
        temp.add(head.val);
    }
}

方法二:棧

public int[] reversePrint(ListNode head) {
        Stack<ListNode> stack = new Stack<>();
        ListNode temp = head;
        while (temp != null) {
            stack.push(temp);
            temp = temp.next;
        }
        int size = stack.size();
        int[] res = new int[size];
        for (int i = 0; i < size; i++) {
            res[i] = stack.pop().val;
        }
        return res;
    }

方法三:逆序儲存

public int[] reversePrint(ListNode head) {
    if (head == null) return new int[]{};// 1. 計算連結串列的長度
    int length = 0;
    ListNode curr = head;
    while (curr != null) {
        length++;
        curr = curr.next;
    }// 2. 初始化存放結果的陣列
    int[] res = new int[length];// 3. 按照反方向將連結串列節點值存放在陣列中
    int i = length - 1;
    curr = head;
    while (curr != null) {
        res[i] = curr.val;
        i--;
        curr = curr.next;
    }return res;
}