字符串反转
Q:给定字符串"Hello,world",实现将其反转
输出结果:dlrow,olleH。
解决思路:使用两个指针,一个指向字符串的首部begin,一个指向字符串尾部end,遍历过程逐渐交换两个指针指向的字符,结束条件begin大于等于end,以下分别为 OC 实现和C实现过程
oc代码实现
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *str = @"Hello,World";
NSMutableString *mutableStr = [NSMutableString stringWithString:str];
NSInteger middle = [str length] / 2;
for (int i = 0; i <= middle; i++)
{
NSString *startStr = [str substringWithRange:NSMakeRange(i, 1)];
NSString *endStr = [str substringWithRange:NSMakeRange([str length] - 1 - i, 1)];
[mutableStr replaceCharactersInRange:NSMakeRange(i, 1) withString:endStr];
[mutableStr replaceCharactersInRange:NSMakeRange([str length] - 1 - i, 1) withString:startStr];
}
NSLog(@"%@",mutableStr);
}
C代码实现
- (void)charReverse
{
NSString * string = @"hello,world";
char ch[100];
memcpy(ch, [string cStringUsingEncoding:NSUTF8StringEncoding], [string length]);
//设置两个指针,一个指向字符串开头,一个指向字符串末尾
char * begin = ch
char * end = ch + strlen(ch) - 1;
//遍历字符数组,逐步交换两个指针所指向的内容,同时移动指针到对应的下个位置,直至begin>=end
while (begin < end)
char temp = *begin;
*(begin++) = *end;
*(end--) = temp;
}
NSLog(@"reverseChar[]:%s",ch);
}
链表反转
反转前:1->2->3->4->NULL
反转后:4->3->2->1->NULL
/** 定义一个链表 */
struct Node {
NSInteger data;
struct Node * next;
};
- (void)listReverse
{
struct Node * p = [self constructList];
[self printList:p];
//反转后的链表头部
struct Node * newH = NULL;
//头插法
while (p != NULL) {
//记录下一个结点
struct Node * temp = p->next;
//当前结点的next指向新链表的头部
p->next = newH;
//更改新链表头部为当前结点
newH = p;
//移动p到下一个结点
p = temp;
}
[self printList:newH];
}
/**
打印链表
@param head 给定链表
*/
- (void)printList:(struct Node *)head
{
struct Node * temp = head;
printf("list is : ");
while (temp != NULL) {
printf("%zd ",temp->data);
temp = temp->next;
}
printf("\n");
}
/** 构造链表 */
- (struct Node *)constructList
{
//头结点
struct Node *head = NULL;
//尾结点
struct Node *cur = NULL;
for (NSInteger i = 0; i < 10; i++) {
struct Node *node = malloc(sizeof(struct Node));
node->data = i;
//头结点为空,新结点即为头结点
if (head == NULL) {
head = node;
}else{
//当前结点的next为尾结点
cur->next = node;
}
//设置当前结点为新结点
cur = node;
}
return head;
}
有序数组合并
以下为有序数组合并的OC实现
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSMutableArray *totalArray = [NSMutableArray array];
NSInteger index1 = 0;
NSInteger index2 = 0;
while (index1 < [firstArray count] && index2 < [secondArray count])
{
NSInteger value1 = [firstArray[index1] integerValue];
NSInteger value2 = [secondArray[index2] integerValue];
if (value1 < value2)
{
index1++;
[totalArray addObject: @(value1)];
}
else
{
index2++;
[totalArray addObject:@(value2)];
}
}
while (index1 < [firstArray count]) {
[totalArray addObject:firstArray[index1]];
index1++;
}
while (index2 < [secondArray count]) {
[totalArray addObject:secondArray[index2]];
index2++;
}
NSLog(@"%@",totalArray);
}
Hash算法
考题:在一个字符串中找到第一个只出现一次的字符,如:输入"abfaccdeff",则输出b。
算法思路:
- 字符(char)是一个长度为8的数据类型,因此总共有256种可能。
- 每个字母根据其ASCII码值作为数组下标对应数组种的一个数字。
- 数组中存储的是每个字符出现的次数。
即利用哈希函数的特点建立 ASCII码值和 index
的联系,存储和查找都通过该函数,有效提高查找效率
这里要注意遍历的时候不是256个全部遍历,仅遍历字符串的长度,代码实现如下:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *str = @"gabfaccdeff";
int array[256] = {};
char *cStr = (char *)[str cStringUsingEncoding:NSUTF8StringEncoding];
for (int i = 0; i < [str length]; i++)
{
char cSubStr = cStr[i];
int index = cSubStr;
array[index] = array[index] + 1;
}
for (int i = 0; i < [str length]; i++)
{
char cSubStr = cStr[i];
int index = cSubStr;
if (array[index] == 1)
{
printf("%c",cSubStr);
break;
}
}
}
查找两个子视图的共同父视图
查找思路:先找出这两个视图所有的父视图,然后通过倒序遍历的方式找出他们共同的父视图
代码实现如下:
- (NSMutableArray *)findSuperViews:(UIView *)view
{
UIView *supView = view.superview;
NSMutableArray *superViewArray = [NSMutableArray array];
while (supView != nil)
{
[superViewArray addObject:supView];
supView = supView.superview;
}
return superViewArray;
}
- (NSMutableArray *)findCommonSuperView:(UIView *)viewOne other:(UIView *)otherView
{
//查找第一个视图的所有父视图
NSMutableArray *oneViewSupers = [self findSuperViews:viewOne];
//查找第十个视图的所有父视图
NSMutableArray *otherViewSupers = [self findSuperViews:otherView];
NSMutableArray *array = [NSMutableArray array];
NSInteger count = MIN([oneViewSupers count], [otherViewSupers count]);
for (int i = 0; i < count;i++)
{
UIView *oneSuperView = oneViewSupers[[oneViewSupers count] - i - 1];
UIView *otherSuperView = otherViewSupers[[otherViewSupers count] - i - 1];
if (oneSuperView == otherSuperView)
{
[array addObject:oneSuperView];
}
else
{
break;
}
}
return array;
}
求无序数组当中的中位数
这个算法有两种解题思路:
- 排序算法 + 中位数
- 利用快排思想(分治思想)
快排思想
任意挑一个元素,以该元素为支点,划分集合为两部分
如果左侧集合长度恰为 (n-1)/2,那么支点恰为中位数
如果左侧长度 <(n - 1)/2,那么中位数在右侧;反之,中位数在左侧
核心代码如下:
int findMedia(int a[],int aLen) {
int low = 0;
int high = aLen - 1;
int mid = (aLen - 1)/2;//中位点
int tempMedia = 0;
while (tempMedia != mid) {
tempMedia = partSort(a, low, high);
if (tempMedia > mid) {//快排的思想确定当前基准数
high = tempMedia - 1;
}else if (tempMedia < mid) {
low = tempMedia + 1;
}else {
break;
}
}
return a[tempMedia];
}
int partSort(int a[],int start, int end) {
int low = start;
int high = end;
int key = a[end];
while (low < high) {
while (low < high) {//左边找比key大的值
if (a[low] <= key) {
low++;
}else {
int temp = a[low];
a[high] = temp;
break;
}
}
while (low < high) {//右边找比key小的值
if (a[high] >= key) {
high--;
}else {
int temp = a[high];
a[low] = temp;
break;
}
}
}
a[low] = key;
return low;
}
总结
链表反转(贝壳、美团面试题)
有序数组合并
Hash算法
查找两个子视图的共同父视图(必考)