0
点赞
收藏
分享

微信扫一扫

7.经典数据结构与算法常见题目(二)

陆公子521 2022-05-06 阅读 51

1.洗衣机问题


int test01(vector<int> vec) {
	if (vec.size() == 0) return 0;
	int size = vec.size();
	int sum = 0;
	for (int i = 0; i < size; i++) {
		sum += vec[i];
	}
	if (sum % size != 0) {
		return -1;
	}
	int avg = sum / size;
	int leftSum = 0;
	int ans = 0;
	for (int i = 0; i < size; i++) {
		int leftRes = leftSum - i * avg;
		int rightRes = (sum - leftSum - vec[i]) - (size - i - 1) * avg;
		if (leftRes < 0 && rightRes < 0) {
			ans = max(ans, abs(leftRes) + abs(rightRes));
		}
		else {
			ans = max(ans, max(abs(leftRes), abs(rightRes)));
		}
		leftSum += vec[i];
	}
	return ans;
}

2.zigzag遍历矩阵

0 1 2 3
4 5 6 7
8 9 10 11

遍历结果为:0 1 4 8 5 2 3 6 9 10 7 11

void printLine(vector<vector<int>>matrix, int ax, int ay, int bx, int by, bool flag) {
    if (flag) {
        //从左下方往右上方移动(bx,by)->(ax,ay)
        while (bx >= ax) {
            printf("%d ", matrix[bx][by]);
            bx--;
            by++;
        }
    }
    else {
        //从右上往左下移动
        while (ay >= by) {
            printf("%d ", matrix[ax][ay]);
            ax++;
            ay--;
        }
    }
}

void test02(vector<vector<int>>matrix) {
    int m = matrix.size();
    int n = matrix[0].size();
    bool up2Down = true;
    int ax = 0;
    int ay = 0;
    int bx = 0;
    int by = 0;
    for (int i = 0; i < m + n - 1; i++)
    {
        printLine(matrix, ax, ay, bx, by, up2Down);
        if (i < m - 1) {
            bx++;
        }
        else {
            by++;
        }
        if (i < n - 1) {
            ay++;
        }
        else {
            ay = n - 1;
            ax++;
        }
        up2Down = !up2Down;
    }
}

3.螺旋打印矩阵

vector<int> test03(vector<vector<int>>& matrix) {
    int top = 0, bottom = matrix.size() - 1;
    int left = 0, right = matrix[0].size() - 1;
    vector<int> res;
    while (left <= right && top <= bottom) {
        for (int i = left; i <= right; i++) {
            res.push_back(matrix[top][i]);
        }
        ++top;
        if (top > bottom) break;

        for (int i = top; i <= bottom; i++) {
            res.push_back(matrix[i][right]);
        }
        --right;
        if (right < left) break;

        for (int i = right; i >= left; i--) {
            res.push_back(matrix[bottom][i]);
        }
        --bottom;
        if (bottom < top) break;

        for (int i = bottom; i >= top; i--) {
            res.push_back(matrix[i][left]);
        }
        ++left;
        if (left > right) break;
    }
    return res;
}

4.给定一个字符串类型的数组arr, 求其中出现次数最多的前k个

class Cmp {
public:
    bool operator()(pair<string, int>& p1, pair<string, int>& p2) {
        return p1.second < p2.second;
    }
};
void test05(vector<string>& arr, int k) {
    priority_queue<pair<string, int>, vector<pair<string,int>>, Cmp> que;
    unordered_map<string, int> map;
    for (int i = 0; i < arr.size(); i++) {
        string tmp = arr[i];
        sort(tmp.begin(), tmp.end());
        map[tmp]++;
    }
    for (const auto& m : map) {
        que.push(m);
    }
    for (int i = 0; i < k; i++) {
        cout << que.top().first << endl;
        que.pop();
    }
}

6.实现一个特殊的栈,在实现栈的基础上再返回栈中最小元素的操作

class Data6 {
public:
    Data6() {

    }
    void push(int val) {
        sta1.push(val);
        if (sta2.empty()) {
            sta2.push(val);
        }
        else {
            if (val <= sta2.top()) {
                sta2.push(val);
            }
        }
    }
    void pop() {
        int tmp = sta1.top();
        sta1.pop();
        if (!sta2.empty() && tmp == sta2.top()){
            sta2.pop();
        }
    }
    int getMin() {
        return sta2.top();
    }

    stack<int> sta1;
    stack<int> sta2;
};

7.用队列实现栈和用栈实现队列

class Data7_1 {
public:
    queue<int> q1, q2;

    Data7_1() {

    }

    void push(int x) {
        if (q1.empty() && q2.empty()) {
            q1.push(x);
            return;
        }
        q2.push(x);
        while (!q1.empty()) {
            q2.push(q1.front());
            q1.pop();
        }

        swap(q1, q2);
    }

    int pop() {
        int tmp = q1.front();
        q1.pop();
        return tmp;
    }

    int top() {
        return q1.front();
    }

    bool empty() {
        return q1.empty() && q2.empty();
    }
};

class Data7_2 {
public:
    stack<int> a;
    stack<int> b;

    Data7_2() {

    }

    void push(int x) {
        a.push(x);
    }

    int pop() {
        if (!b.empty()) {
            int temp = b.top();
            b.pop();
            return temp;
        }
        while (!a.empty()) {
            b.push(a.top());
            a.pop();
        }
        int temp = b.top();
        b.pop();
        return temp;
    }

    int peek() {
        if (!b.empty()) {
            int temp = b.top();
            return temp;
        }
        while (!a.empty()) {
            b.push(a.top());
            a.pop();
        }
        int temp = b.top();
        return temp;
    }

    bool empty() {
        return b.empty() && a.empty();
    }
};

8.给定一个二维数组matrix, 其中每个数都是正数,要求从左上角走到右下角。返回最小的路径和,每一步只能从向右或向下走

int test08_1(vector<vector<int>>& matrix) {
    for (int i = 0; i < matrix.size(); i++) {
        for (int j = 0; j < matrix[i].size(); j++) {
            if (i == 0 && j == 0) continue;
            else if (i == 0 && j != 0) {
                matrix[i][j] += matrix[i][j - 1];
            }
            else if (i != 0 && j == 0) {
                matrix[i][j] += matrix[i - 1][j];
            }
            else if (i != 0 && j != 0) {
                matrix[i][j] += min(matrix[i][j - 1], matrix[i - 1][j]);
            }
        }
    }
    return matrix[matrix.size() - 1][matrix[0].size() - 1];
}

//压缩后
int test08_2(vector<vector<int>>& matrix) {
    vector<int> arr(matrix[0].size());
    arr[0] = matrix[0][0];

    for (int i = 1; i < arr.size(); i++) {
        arr[i] = matrix[0][1] + arr[i - 1];
    }

    for (int i = 1; i < matrix.size(); i++) {
        for (int j = 0; j < matrix[i].size(); j++) {
            if (j == 0) arr[j] += matrix[i][j];
            else {
                arr[j] = min(arr[j], arr[j - 1]) + matrix[i][j];
            }
        }
    }
    return arr[arr.size() - 1];
}

9.给定一个数组arr,所有值非负,将数组看成一个容器,请返回能装多少水,arr = [3,1,2,5,2,4] 可以装5L水

int test09(vector<int>& water ) {
    vector<int> leftMax(water.size());
    vector<int> rightMax(water.size());
    int res = 0;
    for (int i = 1; i < leftMax.size(); i++) {
        leftMax[i] = max(leftMax[i - 1], water[i - 1]);

    }
    for (int i = water.size() - 2; i >= 0; i--) {
        rightMax[i] = max(rightMax[i + 1], water[i + 1]);
    }

    for (int i = 0; i < water.size(); i++) {
        res += std::max(min(leftMax[i], rightMax[i]) - water[i], 0);
    }
    return res;
}

10.给定一个数组arr,可以把任意长度大于0且小于N的前缀作为左半部分,剩下的作为右部分。但是每种划分下都有左部分的最大值和右部分嗯对最大值,请返回最大的,左部分最大值减去右部分最大值的绝对值

int test10(vector<int>& nums) {
    int maxNum = INT_MIN;
    for (int i = 0; i < nums.size(); i++) {
        maxNum = max(nums[i], maxNum);
    }

    return abs(maxNum - min(nums[0], nums[nums.size() - 1]));
}

11.给定一个字符串str,把字符串前面任意的部分挪到后面形成的字符串叫做str的旋转词,比如str = “12345”,旋转词为"12345",“23451”…等,给定两个字符串判断是否互为旋转词

bool test11(string& s1, string& s2) {
    if (s1.size() != s2.size()) {
        return false;
    }
    string s = s1 + s2;
    int tmp = s.find(s2, s2.size());
    return tmp != s.npos;
}
举报

相关推荐

0 条评论