[心得]面试题分析与整理2
来源:互联网 发布:智能化数据分析 编辑:程序博客网 时间:2024/05/22 07:55
继续
5.单链表反转,字符串反转
typedef struct node *nodeLink;struct node{ int data; nodeLink next;};void reverseSigleLink(nodeLink head){ if(!head) return; while(head->next) { nodeLink tmp = head; head->next = NULL; head->next->next = head; head = tmp; }}
字符串反转比这个要简单一些,原因是字符串可以直接按位置进行索引。
#include <stdio.h>void myswap(char *ch1, char *ch2){ if (*ch1 == *ch2) return; *ch1 = *ch1 + *ch2; *ch2 = *ch1 - *ch2; *ch1 = *ch1 - *ch2;}void reverseStr(char *str, int n){ for(int i=0;i<n/2;i++) { myswap(&str[i], &str[n-1-i]); }}int main(){ char str[] = "Hello C.Hello C++.."; printf("raw string is: %s\n", str); char expect[] = "..++C olleH.C olleH"; printf("expect string is: %s\n\n", expect); reverseStr(str, sizeof(str)/sizeof(char)-1); printf("actual output is: %s\n", str); return 0;}
这个题还引申出一个题,就是把字符串按某个字符进行反转。
比如,
Hello C.Hello C++..
期望的反转结果是:
..Hello C++.Hello C
实际的思路就是再多想一层,既然整体可以做反转,那么局部也可以做反转。
先局部反转分隔符之外的字符,然后再对整体做一次反转,应该可以得到结果。原来的反转函数稍作改造,支持按区间做反转。
#include <stdio.h>void myswap(char *ch1, char *ch2){ if (*ch1 == *ch2) return; *ch1 = *ch1 + *ch2; *ch2 = *ch1 - *ch2; *ch1 = *ch1 - *ch2;}void reverseStr(char *str, int left, int right){ for(int i=0;i<(right-left)/2;i++) { //printf("swap str[%d]:%c <-> str[%d]:%c\n", // left+i, str[left+i], right-1-i, str[right-1-i]); myswap(&str[left+i], &str[right-1-i]); }}int main(){ char str[] = "Hello C.Hello C++.."; int str_len = sizeof(str)/sizeof(char) -1; int start = 0; int end = 0; printf("raw string is: %s [%d]chars\n", str, str_len); //char expect[] = "..++C olleH.C olleH"; char expect[] = "..Hello C++.Hello C"; printf("expect string is: %s\n\n", expect); for(int i=0;i<str_len;i++) { if(str[i]=='.' && str[i+1]!='.') { start = i+1; } if(str[i]!='.' && str[i+1]=='.') { end = i; } if(start<end) { //printf("start=%d, end=%d\n",start, end); reverseStr(str, start, end+1); //printf("after partial reverse: %s\n", str); start = end; } } reverseStr(str, 0, str_len); printf("actual output is: %s\n", str); return 0;}
第2段换序列时有点小坑,就是offset要仔细分析。
6.确定两个单链表有共同的部分
这个问题可以演化成判断树有共同祖先的问题,也是面试书上的原题。
基本思路,都往后走,若有共同部分,必然在链表的某个位置会合,如果到尾结点还没会合,那就是没有共同部分,因此这题本质上还是一个单链表的遍历问题。
编程之美233页
#include <iostream>using namespace std;typedef struct Node *NodeLink;struct Node{ int data; NodeLink next;};NodeLink FindNode(NodeLink a, NodeLink b);NodeLink getTail(NodeLink head);int main(){ NodeLink a, b; a = b = 0; FindNode(a, b); return 0;}NodeLink FindNode(NodeLink a, NodeLink b){ if(!a || !b) return NULL; NodeLink tailA = getTail(a); NodeLink tailB = getTail(b); if(tailA==tailB) return tailA; return NULL;}NodeLink getTail(NodeLink head){ if(!head) return NULL; while(head->next) head = head->next; return head;}
7.判断一个ip是一个合法的ip
这个题目本质上是一个字符串遍历的问题。解出一段ip,然判断其值是不是合法,当4段ip值都合法,那就是一个合法的ip。
这个问题还有一个引申问法,就是判断两个ip是不是在同一个网段。这个问题本质是考察IP知识,编码倒不是重点。你得知道怎么判断ip,ip和掩码位与结果相同,那才是两个相同的网段。
具体代码略
8.shell排序
这个问题当时被面过,冒泡,选择,插入,快排,堆排,甚至连最复杂的归排都准备了,唯独希尔排序被问了。希尔排序是用步长控制的插入排序,通过加大插入排序的间隔,让数据大幅移动,时间复杂度NlogN。
还是来段代码说话:
void shell_sort(int *a, int n){ int h,j,k,t; for(h=n/2;h>0;h=h/2) { t = a[j]; for(k=j-h;(k>=0)&&t<a[k];k-=h) { a[k+h] = a[k]; } a[k+h] = t; }}
写起来简单,比快排避开了堆栈调用。
0 0
- [心得]面试题分析与整理2
- [心得]面试题分析与整理
- [心得]面试题分析与整理3
- [心得]面试题分析与整理4
- [心得]面试题分析与整理5
- [心得]面试题分析与整理6
- [心得]面试题分析与整理7
- 2,面试题分析
- android面试题整理(2)
- C#面试题整理2
- Android面试题整理--2
- 面试题整理(2)
- Android面试题整理-2
- Android面试题整理-2
- php面试题收集与整理(一)
- php面试题收集与整理(二)
- php面试题收集与整理(三)
- 2016 JAVA与Android面试题整理
- 自定义ListView
- Android Stuido下NDK的简单实现
- Windows线程同步机制的区别与比较及进程通信方法
- HDU 5914 Triangle【斐波那契数列】
- 图像二维离散傅里叶变换、幅度谱、相位谱
- [心得]面试题分析与整理2
- PHP代码规范
- Android多渠道打包(一):基础多渠道打包
- Java经典多线程问题--生产者与消费者
- 创建链式线性表
- 读书笔记:Effective C++
- Win10 睡眠自动重启的设置 --转自百度知道
- 我笔流心琢工词 也表诚心溢刻字
- USA1586 Molar mass