数据结构---数组(1)
来源:互联网 发布:javac 知乎 编辑:程序博客网 时间:2024/05/18 01:41
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
解题思路:从二维数组的右上角(或左下角)的元素开始判断,因为此元素是它所在行的最大数,是它所在的列的最小数。
如果它等于要查找的数字,则查找过程结束。
如果它大于要查找的数字,则可以排除它所在的列。
如果它小于要查找的数字,则可排除它所在的行。
这样如果要查找的数字不在数组的右上角,则每次判断都可以排除一行或一列以缩小查找范围,直到找到要查找的数字,或者查找范围为空。
下图是在二维数组中查找7的示意图:
java代码实现:
public static void main(String[] args) {int[][] arr = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 },{ 6, 8, 11, 15 }, { 8, 10, 14, 17 } };System.out.println(FindArray(arr, 5, 4, 8));// trueSystem.out.println(FindArray(arr, 5, 4, 22));// false}// rows--二维数组行数(arr.length)// columns--二维数组列数(arr[0].length)// number--要查找的数public static boolean FindArray(int[][] arr, int rows, int columns,int number) {boolean found = false;if (arr != null && rows > 0 && columns > 0) {int row = 0;int column = columns - 1;while (row < rows && column >= 0) {if (arr[row][column] == number) {found = true;break;} else if (arr[row][column] > number) {column--;} else {row++;}}}return found;}
2.旋转数组的最小数字(剑指offer-8)
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1.
解题思路:
1.我们用两个指针,分别指向数组的第一个元素和最后一个元素。按照题目旋转的规则,第一个元素应该是大于或者等于最后一个元素的(还有特例)。
2.接着我们得到处在数组中间的元素。如果该中间元素位于前面的递增子数组,那么它应该大于或者等于第一个指针指向的元素。此时数组中最小的元素应该位于该中间 元素的后面。我们可以把第一指针指向该中间元素,这样可以缩小寻找的范围。
3.如果中间元素位于后面的递增子数组,那么它应该小于或者等于第二个指针指向的元素。此时该数组中最小的元素应该位于该中间元素的前面。我们可以把第二个指针指向该中间元素,这样同样可以缩小寻找的范围。我们接着再用更新之后的两个指针,去得到和比较新的中间元素,循环下去。
按照上述的思路,我们的第一个指针总是指向前面递增数组的元素,而第二个指针总是指向后面递增数组的元素。最后第一个指针将指向前面子数组的最后一个元素, 而第二个指针会指向后面子数组的第一个元素。也就是它们最终会指向两个相邻的元素,而第二个指针指向的刚好是最小的元素。这就是循环结束的条件。
java代码:
public static int MinNumber(int[] numbers , int length){ if(numbers == null || length <= 0) return 0; int index1 = 0; int index2 = length - 1; int indexMid = index1;//旋转为0直接返回numbers[0] while(numbers[index1] >= numbers[index2]) { if(index2 - index1 == 1) { indexMid = index2; break; } indexMid = (index1 + index2) / 2; //如果下标为index1、index2和indexMid指向的三个数字相等,则只能顺序查找 if(numbers[index1] == numbers[index2] && numbers[indexMid] == numbers[index1]) return MinInOrder(numbers , index1 , index2); if(numbers[indexMid] >= numbers[index1]) index1 = indexMid; else if(numbers[indexMid] <= numbers[index2]) index2 = indexMid; } return numbers[indexMid];} //顺序查找public static int MinInOrder(int []numbers , int index1 , int index2){ int result = numbers[index1]; for(int i = index1 + 1 ; i <= index2 ; ++i) { if(result > numbers[i]) result = numbers[i]; } return result;}注意:当两个指针指向的数字及他们中间的数字三者相同的时候,我们无法判断中间的数字是位于前面的字数组还是后面的子数组中,也就无法移动两个指针来缩小查找的范围。此时,我们不得不采用顺序查找的方法。
3.调整数组顺序使奇数位于偶数前面(剑指offer-14)
题目:输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。
解析:设2个头尾指针begin和end, begin从头往前遍历,遇到奇数的话,说明这个数在在正确的位置,所以继续往前遍历直到遇到第一个偶数。同样end指针从后往前遍历,遇到偶数的话,说明这个数在正确的位置,所以继续往前遍历,直到遇到第一个奇数。交换着2个数,然后继续上两步操作,只要满足begin<end;
// 调整数组顺序使奇数位于偶数前面public static void Reorder(int[] pData, int length) {if (pData == null || length == 0)return;int begin = 0;int end = length - 1;while (begin < end) {while (pData[begin] % 2 == 1)begin++;// 从前往后读到第一个偶数while (pData[end] % 2 == 0)end--;// 从后往前,读到第一个奇数if (begin < end)// 这个if是有必要的,不然如果事先已经有序的话,奇偶数交界处的2个数会被调换过来{// 交换前面的第一个偶数和后面的第一个奇数pData[begin] = pData[begin] ^ pData[end];pData[end] = pData[begin] ^ pData[end];pData[begin] = pData[begin] ^ pData[end];begin++;end--;}}}
后续: 数据结构---数组(2)
- 数据结构数组(1)
- 数据结构---数组(1)
- 数据结构之(1)数组
- 数据结构(1)之数组
- 数据结构顺序表1(数组)
- javascript数据结构1-数组
- 数据结构1:数组专题
- 数据结构(六) --- 数组
- 数据结构 队列 (数组)
- 树状数组(数据结构)
- 数据结构---数组(2)
- 数据结构---数组(3)
- 数据结构---数组(4)
- 数据结构---数组(5)
- 2、数组(数据结构)
- Java数据结构(数组篇)
- 数据结构----栈(静态数组)
- [数据结构]Stack(数组)实现
- Java关键字static、final使用小结
- HDU 1024 Max Sum Plus Plus(dp)
- linux 下查找文件和字符串命令 find grep
- Java面试题全集(上)
- 如何让CodeBlocks支持C99
- 数据结构---数组(1)
- List<T>转换为DataTable
- 常用查找算法
- 市场营销书籍推荐
- ukey的密码学原理
- Eclipse中Project Explorer 和 Package Explorer有什么区别
- Push和Pop操作原理
- C语言static 详解
- 1020. Tree Traversals (25)和1385,重建二叉树