[LeetCode] 剑指offer算法题记录 持续更新ing

剑指offer

时隔一年从新开始剑指offer,争取月底以前作完剑指吧,作个小记录。java

Easy

  • 03 数组中的重复数字

能够用HashMap,比较简单,在评论区看到一种比较好的办法,记录一下数组

public int findRepeatNumber(int[] nums) {
        int n = nums.length;
        for (int i = 0;i < n;i ++){
            int cur = nums[i];
            if(cur < 0){
                cur = cur + n;
            }
            if(nums[cur]<0){
                return cur;
            }
            nums[i] = nums[i] - n;
        }
        return -1;
    }
  • 05 替换空格
public String replaceSpace(String s) {
        StringBuilder sb = new StringBuilder();
        for (char c : s.toCharArray()){
            if(c==' ') {
                sb.append("%20");
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }
  • 06 从尾到头打印链表

用栈就好了app

public int[] reversePrint(ListNode head) {
        Stack<ListNode> stack = new Stack<>();
        int count = 0;
        while (head!=null) {
            stack.push(head);
            head = head.next;
            count++;
        }
        int[] result = new int[count];
        count = 0;
        while (!stack.isEmpty()) {
            result[count++] = stack.pop().val;
        }
        return result;

    }
  • 09 用两个栈实现队列
class CQueue {

    /**
     * 前
     * */
    private Stack<Integer> s1;
    /**
     * 后
     * */
    private Stack<Integer> s2;
    public CQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }

    public void appendTail(int value) {
        s2.push(value);
    }

    public int deleteHead() {
        if (!s1.isEmpty()){
            return s1.pop();
        }
        while(!s2.isEmpty())
        {
            s1.push(s2.pop());
        }
        return s1.isEmpty()?-1:s1.pop();
    }
}
  • 10 斐波拉契

简单dpui

public static int fib(int n) {
        if(n<=1)
        {
            return n;
        }
        int[] nums = new int[n+1];
        nums[0] = 0;
        nums[1] = 1;
        for (int i = 2;i <= n;i++)
        {
            nums[i] = nums[i-1]+nums[i-2];
        }
        return nums[n];
    }
  • 11 青蛙跳台阶

和上面相似code

public static int numWays(int n) {
        if(n==0||n==1)
        {
            return 1;
        }
        int[] v = new int[n+1];
        v[0] = 1;
        v[1] = 1;
        v[2] = 2;

        for (int i = 3;i <= n ;i++)
        {
            v[i] = (v[i-1]+v[i-2])%(1000000007);
        }
        return v[n];
    }
  • 11 旋转数组的最小数字

转为二分查找比较合适,可是须要变通一下。队列

public static int minArray(int[] numbers) {
        int left = 0;
        int right = numbers.length-1;
        int mid;
        if(numbers[left]<numbers[right])
        {
            return numbers[left];
        }
        while (left<right)
        {
            if(numbers[left]<numbers[right])
            {
                return numbers[left];
            }
            mid = left + (right - left) / 2;
            if(numbers[mid] < numbers[right])
            {
                right = mid;
            }
            else if(numbers[mid] > numbers[right])
            {
                left = mid + 1;
            }
            else
            {
                right--;
            }
        }
        return numbers[left];
    }
  • 15 二进制中1的个数

第一种办法,比较容易想到,模拟咱们手动求数字二进制形式的过程便可,不断取2的模,而后计数,但须要注意的是,这里n是无符号数,最高位不作符号位,而是数字位,那么符号右移的时候,须要采用java的>>>来进行运算,由于对于有符号的右移,n为负数的时候,最高位会补1,反之补0,但这里n是无符号数,因此这里只能采起无符号右移,也就是默认补0,此外,对于循环的终止条件,不该该用n>0,由于n可能为负数。class

public int hammingWeight(int n) {
        int count = 0;
        int num = n;
        while (num != 0 ){
            int t = num & 1;
            count = count + t;
            num = num >>> 1;
        }
        return count;

    }

第二种办法比较巧,相比于第一种办法突出的地方在于,循环次数减小,由于这里咱们只须要计算1的个数,而其他位数的0咱们并不在意,因此能够用n&(n-1)来消去最右边的1,这样循环次数就变成了1的个数。List

public static int hammingWeight(int n) {
        int count = 0;
        int num = n;
        while (num != 0 ){
            int t = num & 1;
            count = count + t;
            num = num >>> 1;
        }
        return count;
    }

Mid用连

Hard

相关文章
相关标签/搜索