每日一道算法题系列,这些你都会吗
算法题几乎成为了各个大厂的标配,尤其以字节、猿辅导最为代表,多则三四道,少则一两道不等,因此算法这块一定不能忽视。这周的七道热门算法题,你都会做吗?
1、给你一个字符串 s,找到 s 中最长的回文子串
public String longestPalindrome(String s) {
// 特判
if(null==s || s.length()<2) return s;
// 中心扩散法
int res =1; //最大长度
int ll=0; //最大回文串的左指针
int rr=0; //最大回文串的右指针
//将字符串转成char数组,不在循环中去使用str.charAt(i)
char[] chArr =s.toCharArray();
// 开始遍历char数组
for(int i =0; i<chArr.length; i++){
// 以i为中心向两边扩散,寻找最长子串(通俗:回文串为奇数长度i为中心)
int l =i-1;
int r =i+1;
while(l>=0 && r<chArr.length && chArr[l]==chArr[r]){
int len =r-l+1;
if(len>res){
res=len;
ll=l;
rr=r;
}
l--;
r++;
}
// 以i为左指针,i+1为右指针(通俗:回文串为偶数长度)
l=i;
r=i+1;
while(l>=0 && r<chArr.length && chArr[l]==chArr[r]){
int len =r-l+1;
if(len>res){
res=len;
ll=l;
rr=r;
}
l--;
r++;
}
}
return s.substring(ll,rr+1);
}2、二叉树的中序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
// 中序遍历:左 根 右
List<Integer> list = new ArrayList<Integer>();
leftOrder(root,list);
return list;
}
private void leftOrder(TreeNode node, List list){
if(null==node) return;
leftOrder(node.left,list);
list.add(node.val);
leftOrder(node.right,list);
}
}`3、删除链表的倒数第n个位置
#import "SinglyLinkedList.h"
/**
给定一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
输入:head = [1,2], n = 1
输出:[1]
*/
// 2
LinkList removeNthFromEnd(LinkList head, int n) {
if (n < 1) {
return head;
}
LinkList fast = head->next;
LinkList slow = head;
// fast slow固定的间隔
for (int i = 0; i < n; ++i) {
if (!fast) {
return head;
}
fast = fast->next;
}
while (fast) {
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return head;
}
int main(int argc, const char * argv[]) {
Status iStatus;
LinkList L;
iStatus = createLinkList(&L);
for(int j=1; j<=10; j++)
{
insertElemByIndex(&L, 1, j);
}
printList(L);
L = removeNthFromEnd(L, 2);
printList(L);
return 0;
}4、快排
public void quicksort(int [] a,int left,int right)
{
int low=left;
int high=right;
//下面两句的顺序一定不能混,否则会产生数组越界!!!very important!!!
if(low>high)//作为判断是否截止条件
return;
int k=a[low];//额外空间k,取最左侧的一个作为衡量,最后要求左侧都比它小,右侧都比它大。
while(low<high)//这一轮要求把左侧小于a[low],右侧大于a[low]。
{
while(low<high&&a[high]>=k)//右侧找到第一个小于k的停止
{
high--;
}
//这样就找到第一个比它小的了
a[low]=a[high];//放到low位置
while(low<high&&a[low]<=k)//在low往右找到第一个大于k的,放到右侧a[high]位置
{
low++;
}
a[high]=a[low];
}
a[low]=k;//赋值然后左右递归分治求之
quicksort(a, left, low-1);
quicksort(a, low+1, right);
}5、合并K个升序链表
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists.length==0){
return null;
}
//虚拟节点
ListNode head = new ListNode(0);
ListNode tail = head;
//优先队列
PriorityQueue<ListNode> queue = new PriorityQueue<>(lists.length,(a, b)->(a.val-b.val));
//将K个链表头节点合并最小堆
for (ListNode node: lists) {
if (node != null) {
queue.add(node);
}
}
while (!queue.isEmpty()) {
//获取最小节点,放到结果链表中
ListNode node = queue.poll();
tail.next = node;
if (node.next != null) {
queue.add(node.next);
}
//指针链表一直往前
tail = tail.next;
}
return head.next;
}
}6、在二叉树中找到两个节点的最近公共祖先
class Solution {
public:
int lowestCommonAncestor(TreeNode* root, int o1, int o2) {
// write code here
unordered_map<int, int> hash;
queue<TreeNode*> q;
q.push(root);
hash.insert(make_pair(root->val, INT_MAX));
while(q.size()) {
if(hash.count(o1) && hash.count(o2)) //层序遍历提前终止,遍历到o1、o2即可。
break;
auto t = q.front();
auto left = t->left;
auto right = t->right;
q.pop();
if(left) {
hash.insert(make_pair(left->val, t->val));
q.push(left);
}
if(right) {
hash.insert(make_pair(right->val, t->val));
q.push(right);
}
}
unordered_set<int> path;
while(hash.count(o1)) {
path.insert(o1);
o1 = hash[o1];
}
while(!path.count(o2)) {
o2 = hash[o2];
}
return o2;
}
};7、岛屿数量
class Solution {
public:
/**
* 判断岛屿数量
* @param grid char字符型vector<vector<>>
* @return int整型
*/
int solve(vector<vector<char> >& grid) {
// write code here
int res = 0;
int n = grid.size(), m = grid[0].size();
int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if(grid[i][j] == '0')
continue;
else {
res ++;
queue<pair<int, int>> q;
q.push(make_pair(i, j));
while(q.size()) {
auto t = q.front();
q.pop();
grid[t.first][t.second] = '0';
for(int i = 0; i < 4; i ++) {
int x = t.first + dx[i], y = t.second + dy[i];
if(x >= 0 && x < n && y >= 0 && y < m
&& grid[x][y] != '0') {
q.push(make_pair(x, y));
}
}
}
}
}
}
return res;
}
};
更多算法题,可以在这里练习。
#算法##Android##面经##秋招##面试#