9.16(33.(数组)搜索旋转排序数组 17.(字符串)电话号码的字母组合)

本文主要是介绍9.16(33.(数组)搜索旋转排序数组 17.(字符串)电话号码的字母组合),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

33.(数组)搜索旋转排序数组

思路:

1.时间复杂度是(logn),所以我想到了二分查找,但是本题和二分查找还有些不同,二分查找要求整体有序,target和nums[mid]比较以便确定下一步是向左还是向右。因此本体的关键是如何确定向左还是向右。

2.以nums = [4, 5, 6, 7, 0, 1, 2]为例,假如target是0,mid指向7,i指向4,j指向2。target<nums[mid],但是不能向左转。此时的限定条件是target>nums[i]&&target<nums[mid],其他几种情况也是类似。总之判断左转还是右转的条件不再是简单的target和nums[mid]之间的判断。

程序代码如下:

//二分查找的变形,只需在判断条件上是稍微更改即可

class Solution
{
public:int search(vector<int>& nums, int target) {int i = 0, j = nums.size() - 1;//分别表示起始时的坐标if (nums.size() == 1) {if (nums[0] == target) return 0;else return -1;}while (i<j) {int mid = (i + j) / 2;if (target == nums[mid]) return mid;else if (target == nums[i]) return i;else if (target == nums[j]) return j;if (nums[mid] <= nums[j] && nums[mid] <=nums[i]) {//mid处的元素是大的部分,如示例的4、5、6、7if (target<nums[mid] || target>nums[i])j = mid - 1;else if (target<nums[i] && target>nums[mid])i = mid + 1;else return -1;}else if(nums[mid]>=nums[i]&&nums[mid]>=nums[j]){//mid处的元素是小的部分,如示例的0、1、2if (target > nums[i] && target < nums[mid])j = mid - 1;else if (target > nums[mid] || target < nums[j])i = mid + 1;else return -1;}else if (nums[mid] <=nums[j] && nums[mid]>=nums[i]) {//这种情况表示没有进行旋转就是普通的二分查找if (target<nums[mid] && target>nums[i])j = mid - 1;else if (target<nums[j] && target>nums[mid])i = mid + 1;else return -1;}}return -1;}
};

17.(字符串)电话号码的字母组合

思路:分治+递归(我也不清楚这具体算是什么算法)。降低问题规模比如239可以分解成2和39的各种组合,39可以分解成3和9的的组合,递归基就是单个数字的情况。

程序代码如下:
class Solution {
public:string a[10] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};//前两个为空便于后面的i直接使用vector<string> letterCombinations(string digits) {if (digits=="") {vector<string> arr(0);//这个能继续向里面push元素吗?cout<<""<<endl;return arr;//还必须得返回,那就返回空的吧}else if (digits.size() == 1) {int  i = digits[0]-'0';//只有一个元素,该元素的数值是ivector<string> arr(a[i].size());for (int t = 0; t < a[i].size(); t++) {arr[t] = a[i][t];}return arr;}else {int  i = digits[0]-'0';//表示第一个元素数值digits.erase(digits.begin());//除去开头的元素int len1 = a[i].size();//a[i]表示一个字符串int len2 = letterCombinations(digits).size();vector<string> result(len1*len2);//创建新的向量存放元素int m = 0;//表示新向量的坐标for (int j = 0; j < len1; j++) {for (int k = 0; k < len2; k++) {result[m++] = a[i][j] + letterCombinations(digits)[k];}}return result;}}
};

这篇关于9.16(33.(数组)搜索旋转排序数组 17.(字符串)电话号码的字母组合)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/860175

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

poj 2187 凸包or旋转qia壳法

题意: 给n(50000)个点,求这些点与点之间距离最大的距离。 解析: 先求凸包然后暴力。 或者旋转卡壳大法。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <s

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close