android面试冒泡排序简书,android面试笔记总结(算法篇)

Android面试总结(算法篇)

快速排序

每次取一个基准值,然后每次从基准值左边和右边取值,找到基准值左边比基准值大或等于的值,找到基准值右边比基准值小或等于的值,然后左边和右边的值进行交换

完成上面一趟交换后,基准值左边的再进行循环比较,基准值右边的再循环比较

/**

* 快速排序

*

* @param arr

* @param L 指向数组第一个元素

* @param R 指向数组最后一个元素

*/

public static void quickSort(int[] arr, int L, int R) {

int i = L;

int j = R;

//支点以数组的中间的数为准

int pivot = arr[(L + R) / 2];

//左右两端进行扫描,只要两端还没有交替,就一直扫描

while (i <= j) {

//在左边找比支点大的数

while (pivot > arr[i])

i++;

//在右边找比支点小的数

while (pivot < arr[j])

j--;

//此时已经分别找到了比支点小的数(右边)、比支点大的数(左边),它们进行交换

if (i <= j) {

int temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

i++;

j--;

}

for (int m = 0; m < arr.length; m++) {

System.out.print(" " + arr[m]);

}

System.out.println("");

}

//上面一个while保证了第一趟排序支点的左边比支点小,支点的右边比支点大了。

//“左边”再做排序,直到左边剩下一个数(递归出口)

if (L < j)

quickSort(arr, L, j);

//“右边”再做排序,直到右边剩下一个数(递归出口)

if (i < R)

quickSort(arr, i, R);

}

插入排序

//插入排序

public void insertSort(int[] array) {

for (int i = 1; i < array.length; i++) {

int temp = array[i];//当前的值

int j = i - 1;//定位到当前索引的前一个

while (j >= 0 && temp < array[j]) {

//前面的数比当前值要大,则将前面的值替换给当前值

array[j + 1] = array[j];

//位置向前进一位

j--;

}

//将当前值放到最前面的索引

array[j + 1] = temp;

}

}

选择排序

第一层循环表示前面的数,后面一层循环表示后面的数

而冒泡排序的第一层循环表示每一轮循环的次数

public static void order() {

int[] a = {3, 0, 1, 2, 11, 7};

for (int i = 0; i < a.length - 1; i++) {

for (int j = i; j < a.length; j++) {

int temp;

if (a[i] > a[j]) {

temp = a[j];

a[j] = a[i];

a[i] = temp;

}

}

}

for (int i = 0; i < a.length; i++) {

System.out.println("result:" + a[i]);

}

}

冒泡排序

跟选择排序的不同地方是第一层循环表示每一轮循环的次数

public static void sort() {

int[] a = {3, 0, 1, 2, 11, 7};

for (int i = 1; i < a.length; i++) {

for (int j = 0; j < a.length - i; j++) {

if (a[j] > a[j + 1]) {

int temp = a[j + 1];

a[j + 1] = a[j];

a[j] = temp;

}

}

}

for (int i = 0; i < a.length; i++) {

System.out.println("result:" + a[i]);

}

}

二分法查找

排序好的数组,找出对应数的位置,没找到的话返回-1

//二分法查找

public int erfenfa(int[] array, int find) {

int min = 0;

int max = array.length - 1;

int result = -1;

while (min <= max) {

int temp = (max + min) / 2;

//如果要找的数比中间值小,则将最大的索引向左移一位

//,否则将最小的索引向右移一位

if (find < array[temp]) {

max = temp - 1;

} else if (find > array[temp]) {

min = temp + 1;

} else {

result = temp;

break;

}

}

return result;

}

两个栈实现队列

栈的规则是先进后出,后进先出,队列是先进先出,后进后出

public class StackQueue {

Stack stack1 = new Stack();

Stack stack2 = new Stack();

public void push(int node){

//实现队列的push直接将元素放到第一个栈中

stack1.push(node);

}

public int pop(){

//如果第2个栈是空的,需要将第一个栈的数据依次取出来

if(stack2.empty()){

//直到第一个栈中的数据取完了

while(!stack1.empty())

stack2.push(stack1.pop());

}

return stack2.pop();

}

}

链表常见题

常见题型有链表翻转、求倒数第k个节点、判断是不是环形链表、链表部分翻转、链表合并、链表排序等。

链表有一个next指向下一个指针,如果next=null说明到了链表的结束位置,环链表除外,后面题型会涉及到环形链表

public static class ListNode {

int val;

ListNode next = null;

ListNode(int val) {

this.val = val;

}

}

翻转链表

//链表翻转,思想是定义一个节点,然后节点的pre指向了节点的next

//1->2->3->4->5

//5->4->3->2->1

public ListNode revertListNode(ListNode listNode) {

ListNode preNode = null;

ListNode nextNode;

while (listNode != null) {

//先取出next,后面放到listNode的时候用

nextNode = listNode.next;

//preNode指向next节点

listNode.next = preNode;

//将当前节点给到pre,下次判断节点的时候用得到

preNode = listNode;

listNode = nextNode;

}

return preNode;

}

求链表中倒数第k个结点

/**

* 输入一个链表,输出该链表中倒数第k个结点。

*

* @param head

* @param k

* @return

*/

public static ListNode FindKthToTail(ListNode head, int k) {

ListNode second = head;

ListNode first = head;

//双指针的思想,让第一个指针先走,走到第k个结点后,第二个指针也跟着走,

// 当第一个节点走到最后的时候,第二个节点位置就是倒数第k个结点的位置

for (int i = 0; i < k; i++) {

first = first.next;

}

while (first != null) {

first = first.next;

second = second.next;

}

return second;

}

判断一个链表是否有环

/**

* 判断一个链表是不是环形链表

* 定义个块的指针和慢的指针,如果两个再次相遇说明是环形链表

* @param head

* @return

*/

private boolean isLoop(ListNode head) {

//定义快慢指针

ListNode fast = head.next;

ListNode slow = head.next;

while(fast != null && slow != null && fast.next != null) {

//快指针每次走两步,慢指针每次走一步

fast = fast.next.next;

slow = slow.next;

if (fast == slow) {

//如果再次相遇,则说明有环,返回true

return true;

}

}

}

return false;

}

每k位进行翻转链表

每k位翻转链表是在整个链表翻转的基础上演变而来的,它是先将链表分成每k个来进行翻转,然后将当前翻转的结果给上一次翻转结果的最后一个指针

public static ListNode reverse(ListNode head, int k) {

ListNode current = head;

ListNode next = null;

ListNode prev = null;

int count = 0;

//翻转的条件

while (current != null && count < k) {

next = current.next;

current.next = prev;

prev = current;

current = next;

count++;

}

//如果后面还有元素,则递归翻转

if (next != null) {

//将下一次翻转的结果给当前最后一个元素的next位置

head.next = reverse(next, k);

}

return prev;

}

二叉树常见题

二叉树常见题型有二叉树深度计算、二叉树的镜像二叉树、根据二叉树的前序遍历、和中序遍历顺序求出二叉树结构。

二叉树有一个左子节点和右子节点。

public static class TreeNode {

int val;

TreeNode left;

TreeNode right;

TreeNode(int x) {

val = x;

}

}

求二叉树的深度

public static int TreeDepth(TreeNode root) {

//如果当前节点为空,说明已经到底了

if (root == null)

return 0;

//递归调用深度左右子树的深度

int left = TreeDepth(root.left);

int right = TreeDepth(root.right);

//取左右子树大的深度值

return left > right ? left + 1 : right + 1;//每次将调用次数加1

}

输入两棵二叉树A,B,判断B是不是A的子结构

public boolean HasSubtree(TreeNode root1,TreeNode root2) {

boolean result = false;

//如果两个树都不为空才会走这里

if (root2 != null && root1 != null) {

//如果根的值相等

if (root1.val == root2.val) {

//找左右子树是否相等

result = doesTree1HaveTree2(root1, root2);

}

//如果上面分析的结果是不相等,继续判断A树左节点和B树或A右节点和B树

if (!result)

return HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);

}

return result;

}

public boolean doesTree1HaveTree2(TreeNode node1, TreeNode node2) {

//如果右边的树为空直接说明相等

if (node2 == null) {

return true;

}

//如果左边的树为空直接返回不相等,说明不包含

if (node1 == null) {

return false;

}

//如果两个值也不相等,说明也是不相等的

if (node1.val != node2.val) {

return false;

}

//继续递归调用对应的左右子树

return doesTree1HaveTree2(node1.left, node2.left) &&

doesTree1HaveTree2(node1.right, node2.right);

}

求二叉树的镜像二叉树

镜像二叉树是将二叉树在左右方向上旋转下,左边的节点到右边、右边的节点到左边,形如下面:

820bc47859fb

image.png

思路:左右节点进行颠倒,然后递归调用下一个左、右子节点

/**

* 转成镜像二叉树

*

* @param root

*/

public void Mirror(TreeNode root) {

if (root != null) {

TreeNode left = root.left;

TreeNode right = root.right;

TreeNode temp = left;

root.left = right;

root.right = temp;

Mirror(left);

Mirror(right);

}

}

根据二叉树的前序遍历、和中序遍历顺序求出二叉树结构。

树的前序遍历:先是根节点、再到左子节点、再到右子节点

树的中序遍历:先是左子节点、再到根节点、再到右子节点

剑指offer上面一道题,已知前序遍历结果是{1,2,4,7,3,5,6,8},中序遍历结果是{4,7,2,1,5,3,8,6},求该二叉树的结构。

分析:前序遍历第一个节点根节点、然后去中序遍历里面找根节点左边是左子节点、根节点右边的都是右子节点部分,所以我们能确定1是根节点,4、7、2是1的左子节点部分,5、3、8、6是1的右子节点,然后在4、7、2里面继续通过前序遍历的2是首位,能确定2是左子节点,4、7是2的左子节点部分,依次类推,所以有如下结果:

820bc47859fb

image.png

/**

* pre前序的结果:根左右

* in后序的结果:左根右

* pre:{1,2,4,7,3,5,6,8}

* in:{4,7,2,1,5,3,8,6}

*

* @param pre

* @param in

* @return

*/

public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {

TreeNode root = new TreeNode(pre[0]);

for (int i = 0; i < pre.length; i++) {

if (pre[0] == in[i]) {

root.left = reConstructBinaryTree(

Arrays.copyOfRange(pre, 1, i + 1), Arrays.copyOfRange(in, 0, i));

root.right = reConstructBinaryTree(

Arrays.copyOfRange(pre, i + 1, pre.length), Arrays.copyOfRange(in, i + 1, in.length));

}

}

return root;

}

找出一个无序数组中出现超过一半次数的数字

/**

* 计算数组里面超过一半的数字,如果没有这样的数字,则返回0

* 先把数组排序,如果有超过一半的数字,则中间位置的数字一定是该数字

* 然后通过出现该数的次数来判断是否超过一半

*

* @param array

* @return

*/

public static int MoreThanHalfNum_Solution(int[] array) {

Arrays.sort(array);

int temp = array[array.length / 2];

int num = 0;

for (int i = 0; i < array.length; i++) {

if (temp == array[i]) {

num++;

}

}

if (num <= array.length / 2) {

temp = 0;

}

return temp;

}

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

public boolean Find(int target, int [][] array) {

int row=0;

int column=array[0].length-1;

while(row=0){

if(array[row][column]==target){

return true;

}

if(array[row][column]>target){

column--;

}else{

row++;

}

}

return false;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值