以下代码都是我提交过的正确的代码
- 二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
public static boolean Find(int target, int[][] array) {
int height = array.length;
int width = array[0].length;
int i = height - 1;
int j = 0;
while(i >= 0 && j < width){
if(array[i][j] == target)
return true;
else if(array[i][j] > target){
i--;
}
else
j++;
}
return false;
}
- 替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
//Java版
static String replaceSpace(StringBuffer str) {
if(str == null)
return null;
StringBuilder newStr = new StringBuilder();
for(int i = 0; i < str.length();i++){
if(str.charAt(i) == ' '){
newStr.append("%20");
}
else
newStr.append(str.charAt(i));
}
return newStr.toString();
}
//js版
function replaceSpace(str){
if(str == null)
return null;
var reg = /\s/g;//全局替换空格
var result = str.replace(reg,"%20");
return result;
}
- 从尾到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
//用栈存链表的节点
public ArrayList<Integer> printListFromTailToHead(ListNode listNode){
Stack<Integer> stack = new Stack<>();
while(listNode != null){
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> arrayList = new ArrayList<>();
while (!stack.isEmpty()){
arrayList.add(stack.pop());
}
return arrayList;
}
- 用两个栈实现队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
int first = stack1.pop();
while(!stack1.isEmpty()){
stack2.push(first);
first = stack1.pop();
}
while(!stack2.isEmpty()){
stack1.push(stack2.pop());
}
return first;
}
}
- 旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
/*非递减数组:数组中每个元素大于等于上一个元素,所以非递减数组的旋转数组以最小的数字为界,前后都是非递减数组,并且最小的数组小于前面的所有数字,开始递减的位置就是最小数字的索引位置*/
public static int minNumberInRotateArray(int [] array) {
int length = array.length;
if(length ==0)
return 0;
for(int i = 0; i < length - 1; i++){
if(array[i] > array[i+1])
return array[i+1];
}
return array[0];
}
- 斐波那契数列
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
public static int Fibonacci(int n) {
int sum = 0;
int pre1 = 1; //前一个
int pre2 = 1; //前两个个
if(n <= 0)
return 0;
if(n == 1 || n ==2)
return 1;
else {
for(int i = 3; i < n + 1; i++){
sum = pre1 + pre2;
pre1 = pre2;
pre2 = sum;
}
}
return sum;
}
- 跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
//斐波那契数列 1 2 3 5 8 13 21
// 一次只能走一步或者两步,拿f(4)来说,f(3)走的路径f(4)也能走,f(2)走的路径f(4)也能走,所以f(4)=f(2)+f(3)
public static int JumpFloor(int target) {
int sum = 0;
int pre1 = 1; //前一个
int pre2 = 2; //前两个
if(target <= 0) return 0;
if(target == 1) return 1;
if(target == 2) return 2;
else {
for(int i = 2; i < target; i++){
sum = pre1 + pre2;
pre1 = pre2;
pre2 = sum;
}
}
return sum;
}
- 变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
/************解一***********/
//f(n)=f(n-1)+f(n-2)+f(n-3)+...+f(1)+1
public int JumpFloorII(int target) {
if(target == 0) return 0;
int[] bt = new int[target + 1];
bt[0] = 1;
bt[1] = 1;
for(int i = 2; i <= target; i++){
bt[i] = 0;
for(int j = 0; j < i; j++){
bt[i] += bt[j];
}
}
return bt[target];
}
- 矩形覆盖
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
//这个题类似于简单的跳台阶,f(n)=f(n-1)+f(n-2)
public static int RectCover(int target) {
int num = 0;
if(target == 0 || target == 1 || target == 2)return target;
int pre1 = 1; // 第一张
int pre2 = 2; // 第二张
for(int i = 3; i <= target; i++){
num = pre1 + pre2;
pre1 = pre2;
pre2 = num;
}
return num;
}
/************解二***********/
public static int JumpFloor(int target) {
if(target == 0) return 0;
int[] bt = new int[target + 1];
bt[0] = 1;
bt[1] = 1;
for(int i = 2; i <= target; i++){
//既然f(n)=f(n-1)+f(n-2)+...+f(1)+1,那么f(n+1)=f(n)+f(n)-1+1
bt[i] = bt[i-1] + bt[i-1] - 1 + 1;
}
return bt[target];
}
- 二进制中1的个数
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
public class Solution {
public static int NumberOf1(int n) {
int num = 0;
char[] charArray = Integer.toBinaryString(n).toCharArray();
for(int i = 0; i < charArray.length; i++){
if(charArray[i] == '1'){
num++;
}
}
return num;
}
}
- 数值的整数次方
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
public static double Power(double base, int exponent) {
//java中浮点数的范围为-Double.MAX_VALUE~-Double.MIN_NORMAL
//以及Double.MIN_NORMAL~-Double.MAX_VALUE
double num = 1.0;
if(base == 0) return 0;
int tempExponent = Math.abs(exponent);
for(int i = 0; i < tempExponent; i++){
num *= base;
if(num > Double.MAX_VALUE) {
System.out.println("ERROR超出最大浮点数的范围");
return -1;
}
if(num < -Double.MAX_VALUE) {
System.out.println("ERROR超出最小浮点数的范围");
return -1;
}
if(num > -Double.MIN_NORMAL && num < Double.MIN_NORMAL){
System.out.println("ERROR在最大负浮点数和最小正浮点数的范围内,不被允许");
return -1;
}
}
//根据指数的正负来判断结果是否是其倒数
return exponent > 0?num:1/num;
}
- 调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
/**********************解1**********************/
//首先找到最开始的那个偶数的a,下标是n1,然后找到离这个偶数最近的奇数b,下标是n2,让a到b-1之间的数字向后移动一位,奇数b移到n1处,继续
public void reOrderArray(int [] array) {
int length = array.length;
for(int i = 0; i < length; i++){
int index = 0;
boolean flag = false;
if(array[i]%2==0){
for(int j = i + 1; j < length; j++){
if(array[j] % 2 ==1){
index = j;
flag = true;
break;
}
}
if(flag){
int temp = array[index];
for(int m = index; m > i; m--){
array[m] = array[m-1];
}
array[i] = temp;
}
}
}
}
/**********************解2**********************/
//新开辟两个数组,将偶数和奇数分别存入两个数组,最后拼接,这种方法时间复杂度是最小的
public class Solution {
public void reOrderArray(int [] array) {
int length = array.length;
int[] even = new int[length];
int[] odd = new int[length];
int evenIndex = 0;
int oddIndex = 0;
for(int i = 0; i < length; i++){
if(array[i] % 2 == 0){
even[evenIndex] = array[i];
evenIndex++;
}
else{
odd[oddIndex] = array[i];
oddIndex++;
}
}
for(int i = 0; i < oddIndex; i++){
array[i] = odd[i];
}
for(int i = oddIndex; i < length; i++)
array[i] = even[i - oddIndex];
}
}
- 链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点。
//先统计节点的个数,然后循环找到倒数第k个节点
public ListNode FindKthToTail(ListNode head,int k) {
int count = 0;
ListNode tempNode = head;
while(tempNode != null){
count++;
tempNode = tempNode.next;
}
if(count < k)
return null;
ListNode p = head;
for(int i = 1; i <= count - k; i++){
p = p.next;
}
return p;
}
- 反转链表
输入一个链表,反转链表后,输出新链表的表头。
//存下当前节点的下一节点,当前节点的下一节点指向前一节点,前一节点等于当前节点,当前节点等于存下的下一节点。
public ListNode ReverseList(ListNode head) {
ListNode pre = null;
ListNode next = null;
if(head == null)
return null;
while(head != null){
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
- 合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
//一个简单的递归
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode pHead = null;
if(list1 == null)return list2;
if(list2 == null)return list1;
if(list1.val < list2.val){
pHead = list1;
pHead.next = Merge(list1.next, list2);
}else {
pHead = list2;
pHead.next = Merge(list1, list2.next);
}
return pHead;
}
- 二叉树的镜像
操作给定的二叉树,将其变换为源二叉树的镜像。
public void Mirror(TreeNode root) {
if(root == null) return;
if(root.left == null && root.right == null) return;
//交换左右子树
TreeNode treeNode = null;
treeNode = root.left;
root.left = root.right;
root.right = treeNode;
if(root.left != null)
Mirror(root.left);
if(root.right != null)
Mirror(root.right);
}
//树的结构
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
- 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
//查找的顺序是 left->right top->bottom right->left bottom->top 控制好边界条件
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
int row = matrix.length; //行
int col = matrix[0].length; //列
int left = 0, top = 0, right = col - 1, bottom = row - 1;
//循环结束条件
while(left <= right && top <= bottom){
//left -> right
for(int i = left; i <= right; i++) arrayList.add(matrix[top][i]);
//top -> bottom
for(int i = top + 1; i <= bottom; i++) arrayList.add(matrix[i][right]);
//right -> left
if(top != bottom) //从left -> right就结束了,防止再次计算
for(int i = right - 1; i >= left; i--) arrayList.add(matrix[bottom][i]);
//bottom -> top
if(left != right) //从top -> bottom就结束了,防止再次计算
for(int i = bottom - 1; i > top; i--)arrayList.add(matrix[i][left]);
left++;right--;top++;bottom--;
}
return arrayList;
}
- 包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
import java.util.Stack;
public class Solution {
Stack<Integer> stack = new Stack<Integer>();
Stack<Integer> minstack = new Stack<Integer>();
public void push(int node) {
stack.push(node);
if(minstack.empty())
minstack.push(node);
//判断新押入stack的数值是否小于等于minstack的栈顶
else if(node <= minstack.peek())
minstack.push(node);
}
//如果minstack的栈顶和原stack栈顶一样大,弹出minstack的栈顶
public void pop() {
if(stack.peek() == minstack.peek())
minstack.pop();
stack.pop();
}
//获取stack的栈顶
public int top() {
return stack.peek();
}
//获取minstack的栈顶
public int min() {
return minstack.peek();
}
}
- 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
import java.util.ArrayList;
import java.util.Stack; //不要忘记导包!!!
//模拟弹出的过程
public class Solution {
public boolean IsPopOrder(int [] pushA,int [] popA) {
if(pushA.length != popA.length || pushA.length == 0 || popA.length == 0)
return false;
Stack<Integer> tempStack = new Stack<Integer>();
int index = 0;
for(int i = 0; i < pushA.length; i++){
tempStack.push(pushA[i]);
while(index < popA.length && tempStack.peek() == popA[index]){
tempStack.pop();
index++;
}
}
return tempStack.isEmpty()?true:false;
}
}