剑指offer_牛客网_编程题_Java

目录

二维数组中的查找

替换空格

从尾打印链表

重建二叉树

用两个栈实现队列

旋转数组的最小数字

斐波那契数列

跳台阶

变态跳台阶

矩形覆盖

二进制中1的个数

数值的整数次方

调整数组顺序使奇数位于偶数前面

链表中倒数第k个结点

反转链表

 


二维数组中的查找

从右上角开始查找,如果小于target, 排除最后一列,如果大于target,排除第一行,然后取当前右上角如上述方法再次查找,直至右上角元素等于target,或者所有行和列都被淘汰。复杂度O(n) 。 T(2*n)

public class Solution {
    public boolean Find(int target, int [][] array) {
            //判断array是否为空需要进行三次判断,当array=null 时,访问array.length 非法
           if(array==null||array.length==0||(array.length==1&&array[0].length==0)) return false;
           int i = 0, j = array.length-1;
           while(i < array.length && j >= 0)
           {
               if(target == array[i][j]) return true;
               else if(target < array[i][j]) j--;
               else i++;
           }
        return false;
    }
}

替换空格

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

从尾打印链表

/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
    
    public void Dfs(ArrayList<Integer> ans,ListNode listNode)
    {
        if(listNode == null) return ;
        Dfs(ans,listNode.next);
        ans.add(listNode.val);
    }
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> ans = new ArrayList<>();
        Dfs(ans,listNode);
        return ans;
    }
}

重建二叉树

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    
    public TreeNode Dfs(int l1, int r1, int l2, int r2, int[] pre, int[] in)
    {
        if(l1 > r1 || l2 > r2) return null;
        TreeNode root = new TreeNode(pre[l1]);
        int i;
        for(i = l2; i <= r2; i++)
            if(in[i] == pre[l1]) break;
        root.left = Dfs(l1+1,l1+i-l2, l2, i-1, pre, in);
        root.right = Dfs(l1+i-l2+1, r1, i+1, r2, pre, in);
        return root;
    }
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        return Dfs(0, pre.length-1, 0, in.length-1, pre, in);
    }
}

用两个栈实现队列

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        while(!stack2.empty()) stack1.push(stack2.pop());
        stack2.push(node);
        while(!stack1.empty()) stack2.push(stack1.pop());
    }
    
    public int pop() {
       return stack2.pop();
    }
}

旋转数组的最小数字

import java.util.ArrayList;
public class Solution {
    public int minNumberInRotateArray(int [] array) {
     int temp = array[0],mina = array[0];
     for(int i = 1; i < array.length; i++)
         mina = Math.min(mina,array[i-1] = array[i]);
     array[array.length-1] = temp;
     return mina;
    }
}

斐波那契数列

public class Solution {
    public int Fibonacci(int n) {
        int[] f = {0,1,1};
        int i = 3;
        while(i <= n)
        {
            f[i%3] = f[(i-1)%3] + f[(i-2)%3];
            i++;
        }
        return f[n%3];
    }
}

跳台阶

public class Solution {
    public int JumpFloor(int target) {
         int[] f = {0,1,2};
         int i = 3;
        while(i <= target)
        {
            f[i%3] = f[(i-1)%3] + f[(i-2)%3];
            i++;
        }
        return f[target%3];
    }
}

变态跳台阶

public class Solution {
    public int JumpFloorII(int target) {
        int ans = 0;
        int sum = 0;
        while(target > 0)
        {
            ans = sum+1;
            sum += ans;
            target--;
        }
        return ans;
    }
}

矩形覆盖

public class Solution {
    public int RectCover(int target) {
        int[] f = {0,1,2};
        int i = 3;
        while(i <= target)
        {
            f[i%3] = f[(i-1)%3] + f[(i-2)%3];
            i++;
        }
        return f[target%3];
    }
}

二进制中1的个数

public class Solution {
    public int NumberOf1(int n) {
        int res = 0;
        long m = n;
        if(n < 0) {
            m = (long)(Math.pow(2,32))+n;
        }
        while(m > 0) 
        {
            if((m & 1) == 1) res++;
            m >>= 1;
        }
        return res;
    }
}

数值的整数次方

采用快速幂比较快,不过要注意底数和指数为负数的情况

public class Solution {
    
    double fpow(double x, int n)
    {
        double t = 1;
        if(x < 0) {x = -x; if((n&1) == 1) t = -1;}
        if(n == 0) return 1;
        double res = 1;
        boolean temp = true;
        if(n < 0) {temp = false; n = -n;}
        while(n > 0)
        {
            if((n & 1) == 1) res *= x;
            if(temp) x *= 2;
            else x /= 2;
            n >>= 1;
        }
        return res*t;
    }
    
    public double Power(double base, int exponent) {
        return fpow(base,exponent);
  }
}

调整数组顺序使奇数位于偶数前面

先安利一个python 的一行代码,真是强大。

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        return sorted(array,key = lambda c : c%2, reverse = True)

然后Java,有两种做法,一种是牺牲空间换时间,再开一个数组来辅助求解,时间复杂度为O(n), 另一种则是利用冒泡或者插入排序中交换的思想,来实现,时间复杂度O(n^2)。

方法一:

arraycopy 为深度拷贝

public class Solution {
    public void reOrderArray(int [] array) {
       int[] temp = new int[array.length];
       int x = 0; 
       for(int i = 0; i < array.length; i++)
            if(array[i] % 2 == 1)temp[x++] = array[i];
       for(int i = 0; i < array.length; i++)
            if(array[i] % 2 == 0)temp[x++] = array[i];
      // for(int i = 0; i < array.length; i++)
      //      array[i] = temp[i];
       System.arraycopy(temp, 0, array, 0, temp.length);
    }
}

方法二:

用异或进行swap还是比较有意思的。

public class Solution {
    public void reOrderArray(int [] array) {
        for(int i = 0; i < array.length; i++)
        {
            if(array[i] % 2 == 1)
            for(int j = i-1; j >= 0; j--)
              if(array[j] % 2 == 0) 
              {
                  array[j] = array[j] ^ array[j+1];
                  array[j+1] = array[j] ^ array[j+1];
                  array[j] = array[j] ^ array[j+1];
              }
        }
    }
}

链表中倒数第k个结点

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        ListNode temp = head;
        int n = 0;
        while(temp != null) {n++;temp = temp.next;}
        if(k <= 0 || head == null || k > n) return null;
        n = n-k;
        temp = head;
        while(n > 0) {n--;temp = temp.next;}
        return temp;
    }
}

反转链表

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
        ListNode res = new ListNode(0);
        while(head != null){
            ListNode temp = new ListNode(head.val);
            temp.next = res.next;
            res.next = temp;
            head = head.next;
        }
        return res.next;
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值